Fraction.st
changeset 24281 69518cfc5366
parent 24265 2bc155f7d89b
child 24931 843e3aaea193
--- a/Fraction.st	Fri Jun 07 02:34:29 2019 +0200
+++ b/Fraction.st	Fri Jun 07 02:34:43 2019 +0200
@@ -797,6 +797,61 @@
     "
 !
 
+asQuadFloat
+    "return a QuadFloat with (approximately) my value.
+     Since floats have a limited precision, you usually loose bits when doing this."
+
+    |num den numShift denShift numBits rslt|
+
+    (numerator class == SmallInteger and:[denominator class == SmallInteger]) ifTrue:[
+        ^ (numerator asQuadFloat) / (denominator asQuadFloat)
+    ].
+
+    "Do it the hard way: reduce magnitude and undo reduction on the quotient"
+
+    numBits := QuadFloat precision * 2.    "number of bits to preserve (conservative)"
+    num := numerator abs.
+    numShift := numBits - num highBit. "(num highBit - bits) negated"
+    numShift < 0 ifTrue:[num := num bitShift:numShift] ifFalse:[ numShift := 0].
+
+    den :=  denominator.
+    denShift := numBits - den highBit. "(den highBit - bits) negated"
+    denShift < 0 ifTrue:[den := den bitShift:denShift] ifFalse:[denShift := 0].
+
+    rslt := (num asQuadFloat / den asQuadFloat) * (2 raisedToInteger:denShift-numShift).
+    numerator negative ifTrue:[ ^ rslt negated ].
+    ^ rslt.
+
+    "
+      (5/9) asQuadFloat
+      (-5/9) asQuadFloat
+      (Fraction basicNew setNumerator:500000000000 denominator:900000000000) asQuadFloat = (5/9) asQuadFloat
+      (Fraction basicNew setNumerator:500000000001 denominator:900000000000) asQuadFloat = (5/9) asQuadFloat
+      (500000000001/900000000000) asQuadFloat
+      (-500000000001/900000000000) asQuadFloat
+      (500000000001/900000000000) asQuadFloat = (5/9) asQuadFloat
+
+      (500000000000/9) asQuadFloat
+      (5/900000000000) asQuadFloat
+      89012345678901234567 asFloat / 123456789123456789 asQuadFloat
+      (89012345678901234567 / 123456789123456789) asQuadFloat
+      (-89012345678901234567 / 123456789123456789) asQuadFloat
+
+      (
+       180338700661043257034670206806167960222709397862806840937993331366591676308781197477183367018067356365812757479444845320188679437752013593674158587947149815441890236037219685250845721864713487208757788709113534916165172927384095182655935222723385253851776639985379367854545495930551624041981995105743408203125
+        /
+       180331613628627651967947866455016278082980736719853750685591387625058011528928110602436691256100991596843001549483950600930062886280582766771424470965440873615557144641435276844465734361353086032476712374317224249252177316815544331763696909434844464464323192083930469387098582956241443753242492675781250
+      ) asQuadFloat
+
+      180338700661043257034670206806167960222709397862806840937993331366591676308781197477183367018067356365812757479444845320188679437752013593674158587947149815441890236037219685250845721864713487208757788709113534916165172927384095182655935222723385253851776639985379367854545495930551624041981995105743408203125
+         asQuadFloat /
+      180331613628627651967947866455016278082980736719853750685591387625058011528928110602436691256100991596843001549483950600930062886280582766771424470965440873615557144641435276844465734361353086032476712374317224249252177316815544331763696909434844464464323192083930469387098582956241443753242492675781250
+         asQuadFloat
+    "
+
+    "Created: / 07-06-2019 / 02:32:19 / Claus Gittinger"
+!
+
 asShortFloat
     "return a short float with (approximately) my value"