help-smalltalk
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Help-smalltalk] Interesting Float to Fraction conversion


From: Paolo Bonzini
Subject: Re: [Help-smalltalk] Interesting Float to Fraction conversion
Date: Fri, 27 Oct 2006 08:25:59 +0900
User-agent: Thunderbird 1.5.0.7 (Macintosh/20060909)

With the included patch, I get:

st> x := 1.14474205677314q-13.
st> x asFraction printNl.
st> (x asFraction - x) printNl!
2931673387916173/25609903738315777422401732608
1.40129846432481707092372958329q-45

That's pretty good.

Thanks,

Paolo
--- orig/kernel/Float.st
+++ mod/kernel/Float.st
@@ -221,7 +221,7 @@ asFraction
     "Convert the receiver into a fraction with a good (but undefined)
      approximation"
 
-    | a x n2 d2 n1 d1 n0 d0 eps abs |
+    | a x n2 d2 n1 d1 n0 d0 eps abs gcd |
 
     self checkCoercion.
 
@@ -232,8 +232,8 @@ asFraction
 
     n1  := d0 := 0.
     n0  := d1 := 1.
-    abs := self abs.
-    eps := self class epsilon * 1024.  "Number out of a hat"
+    abs := self abs timesTwoPower: self exponent negated.
+    eps := self class epsilon.
     x   := abs.
 
     [   a := x truncated.
@@ -245,6 +245,14 @@ asFraction
            ((self coerce: n0) / (self coerce: d0) - abs) abs < eps ]
     ]   whileFalse.
 
+    self abs < 1
+       ifTrue: [ d0 := d0 * (2 raisedToInteger: self exponent negated) ]
+       ifFalse: [ n0 := n0 * (2 raisedToInteger: self exponent) ].
+
+    gcd := n0 gcd: d0.
+    n0 := n0 quo: gcd.
+    d0 := d0 quo: gcd.
+
     ^Fraction
        numerator: (self < 0 ifTrue: [ n0 negated ] ifFalse: [ n0 ])
        denominator: d0

reply via email to

[Prev in Thread] Current Thread [Next in Thread]