--- a/Fraction.st Tue Jun 11 23:44:10 2002 +0200
+++ b/Fraction.st Tue Jun 11 23:45:07 2002 +0200
@@ -230,7 +230,7 @@
denominator:denominator)
].
aNumber isFraction ifTrue:[
- aNumber isFixedPoint ifFalse:[ "/ the value was corrent, but the scale is lost
+ aNumber isFixedPoint ifFalse:[ "/ the value was correct, but the scale is lost
n := aNumber numerator.
d := aNumber denominator.
@@ -245,7 +245,7 @@
]
].
(aNumber isMemberOf:Float) ifTrue:[
- ^ aNumber + (numerator asFloat / denominator asFloat)
+ ^ aNumber + self asFloat
].
^ aNumber sumFromFraction:self
@@ -413,23 +413,46 @@
asFloat
"return a float with (approximately) my value"
- |num den numB denB bits|
+ |num den numShift denShift bits|
(numerator class == SmallInteger and:[denominator class == SmallInteger]) ifTrue:[
^ (numerator asFloat) / (denominator asFloat)
].
- "Do it the hard way: make numbers smaller and redo this on the quotient"
+ "Do it the hard way: reduce magnitude and undo reduction on the quotient"
- bits := Float zero numberOfBits * 2. "number of bits to preserve (conservative)"
+ bits := Float precision * 2. "number of bits to preserve (conservative)"
num := numerator abs.
- den := denominator abs.
- numB := num highBit - bits.
- numB > 0 ifTrue:[num := num bitShift:numB negated].
- denB := den highBit - bits.
- denB > 0 ifTrue:[den := den bitShift:denB negated].
+ numShift := bits - num highBit. "(num highBit - bits) negated"
+ numShift < 0 ifTrue:[num := num bitShift:numShift] ifFalse:[numShift := 0].
+
+ den := denominator.
+ denShift := bits - den highBit. "(den highBit - bits) negated"
+ denShift < 0 ifTrue:[den := den bitShift:denShift] ifFalse:[denShift := 0].
+
+ ^ (num asFloat / den asFloat) * (2.0 raisedToInteger:denShift-numShift) * (num sign)
- ^ (num asFloat / den asFloat) * (2.0 raisedToInteger:numB-denB) * (num sign)
+ "
+ (5/9) asFloat
+ (-5/9) asFloat
+ (500000000000/900000000000) asFloat
+ (-500000000000/900000000000) asFloat
+ (500000000000/9) asFloat
+ (5/900000000000) asFloat
+ 89012345678901234567 asFloat / 123456789123456789 asFloat
+ (89012345678901234567 / 123456789123456789) asFloat
+
+ (
+ 180338700661043257034670206806167960222709397862806840937993331366591676308781197477183367018067356365812757479444845320188679437752013593674158587947149815441890236037219685250845721864713487208757788709113534916165172927384095182655935222723385253851776639985379367854545495930551624041981995105743408203125
+ /
+ 180331613628627651967947866455016278082980736719853750685591387625058011528928110602436691256100991596843001549483950600930062886280582766771424470965440873615557144641435276844465734361353086032476712374317224249252177316815544331763696909434844464464323192083930469387098582956241443753242492675781250
+ ) asFloat
+
+ 180338700661043257034670206806167960222709397862806840937993331366591676308781197477183367018067356365812757479444845320188679437752013593674158587947149815441890236037219685250845721864713487208757788709113534916165172927384095182655935222723385253851776639985379367854545495930551624041981995105743408203125
+ asFloat /
+ 180331613628627651967947866455016278082980736719853750685591387625058011528928110602436691256100991596843001549483950600930062886280582766771424470965440873615557144641435276844465734361353086032476712374317224249252177316815544331763696909434844464464323192083930469387098582956241443753242492675781250
+ asFloat
+ "
!
asFraction
@@ -451,11 +474,19 @@
!
asShortFloat
- "return a shortFloat with (approximately) my value"
+ "return a short float with (approximately) my value"
+
+ (numerator class == SmallInteger and:[denominator class == SmallInteger]) ifTrue:[
+ ^ (numerator asShortFloat) / (denominator asShortFloat)
+ ].
- ^ (numerator asShortFloat) / (denominator asShortFloat)
+ ^ self asFloat asShortFloat
- "Created: 17.4.1996 / 12:21:08 / cg"
+ "
+ (5/9) asShortFloat
+ (500000000000/900000000000) asShortFloat
+ (500000000000/9) asShortFloat
+ "
!
coerce:aNumber
@@ -691,12 +722,11 @@
gcd := numerator gcd:den.
(gcd ~~ 1) ifTrue:[
+ gcd < 0 ifTrue:[
+ gcd := gcd negated.
+ ].
numerator := numerator // gcd.
denominator := den := den // gcd.
- den < 0 ifTrue:[
- numerator := numerator negated.
- den := denominator := den negated.
- ].
(den == 1) ifTrue:[^ numerator].
].
^ self
@@ -821,6 +851,6 @@
!Fraction class methodsFor:'documentation'!
version
- ^ '$Header: /cvs/stx/stx/libbasic/Fraction.st,v 1.55 2002-06-11 10:06:42 stefan Exp $'
+ ^ '$Header: /cvs/stx/stx/libbasic/Fraction.st,v 1.56 2002-06-11 21:45:07 stefan Exp $'
! !
Fraction initialize!