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: J Pfersich
Subject: Re: [Help-smalltalk] Interesting Float to Fraction conversion
Date: Thu, 02 Nov 2006 15:21:25 -0700

Thanks, that works.

At 08:25 AM 10/27/2006 +0900, Paolo Bonzini wrote:
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]