[squeak-dev] asApproximateFraction[AtOrder:]
Eliot Miranda
eliot.miranda at gmail.com
Mon Apr 23 20:23:03 UTC 2018
Hi All,
asApproximateFraction isn't that useful. It is based on
asApproximateFractionAtOrder:, which gives you the best fraction it can
find up to order. e.g.
testContinuedFractions
self assert: (Float pi asApproximateFractionAtOrder: 1) = (22/7).
self assert: (Float pi asApproximateFractionAtOrder: 3) = (355/113)
Here's 32-bit Float 1/3:
((FloatArray new: 1) at: 1 put: 1/3; at: 1) 0.3333333432674408
((FloatArray new: 1) at: 1 put: 1/3; at: 1) asApproximateFraction
(11184811/33554432)
That's not what I expected :-). The problem is that
asApproximateFractionAtOrder: is great if you know the number you're
dealing with, but if you don't then it'll give you too much information.
[This value comes up in the vm parameters system report page, where 1/3 is
the ratio of growth to heap size above which a full GC is performed, i.e.
by default every time a scavenge causes the heap grows by 1/3 from the last
time a full GC was performed, the system will do a full GC. It would be
great to report this as 1/3, not 0.33333298563957214, which is what's
emerging from the C code in the VM].
Let's get a feeling for orders; they're effectively negative powers of 10:
(1 to: 20) collect: [:order| | f |
{ order. (f := Float pi asApproximateFractionAtOrder: order). f asFloat. (f
asFloat - Float pi) abs}]
{{1 . (22/7) . 3.142857142857143 . 0.0012644892673496777}.
{2 . (333/106) . 3.141509433962264 . 8.32196275291075e-5}.
{3 . (355/113) . 3.1415929203539825 . 2.667641894049666e-7}.
{4 . (103993/33102) . 3.1415926530119025 . 5.778906242426274e-10}.
{5 . (104348/33215) . 3.141592653921421 . 3.3162805834763276e-10}.
{6 . (208341/66317) . 3.1415926534674368 . 1.2235634727630895e-10}.
{7 . (312689/99532) . 3.1415926536189365 . 2.914335439641036e-11}.
{8 . (833719/265381) . 3.141592653581078 . 8.715250743307479e-12}.
{9 . (1146408/364913) . 3.141592653591404 . 1.6107115641261771e-12}.
{10 . (4272943/1360120) . 3.141592653589389 . 4.04121180963557e-13}.
{11 . (5419351/1725033) . 3.1415926535898153 . 2.220446049250313e-14}.
{12 . (80143857/25510582) . 3.1415926535897927 . 4.440892098500626e-16}.
{13 . (245850922/78256779) . 3.141592653589793 . 0.0}.
{14 . (817696623/260280919) . 3.141592653589793 . 0.0}.
{15 . (19052873251/6064717916) . 3.141592653589793 . 0.0}.
{16 . (19870569874/6324998835) . 3.141592653589793 . 0.0}.
{17 . (19870569874/6324998835) . 3.141592653589793 . 0.0}.
{18 . (19870569874/6324998835) . 3.141592653589793 . 0.0}.
{19 . (19870569874/6324998835) . 3.141592653589793 . 0.0}.
{20 . (19870569874/6324998835) . 3.141592653589793 . 0.0}}
More useful would be something like:
asApproximateFractionToEpsilon: epsilon
"Answer a Fraction approximating the receiver. This conversion uses the
continued fraction method to approximate a floating point number."
1 to: 12 do:
[:order| | fraction |
fraction := self asApproximateFractionAtOrder: order.
(fraction - self) abs <= epsilon ifTrue:
[^fraction]].
^ self asApproximateFractionAtOrder: 0
and then instead of
asApproximateFraction
"Answer a Fraction approximating the receiver. This conversion uses the
continued fraction method to approximate a floating point number."
^ self asApproximateFractionAtOrder: 0
one could have
asApproximateFraction
"Answer a Fraction approximating the receiver. This conversion uses the
continued fraction method to approximate a floating point number."
^self asApproximateFractionToEpsilon: 1e-6
And hence
{ 0.0. 0.333. 0.5. 1.0. Float pi . ((FloatArray new: 1) at: 1 put: 1/3; at:
1) } collect:
[:n| n asApproximateFractionToEpsilon: 1e-6]
{0 . (333/1000) . (1/2) . 1 . (355/113) . (1/3)}
Votes for or against changing asApproximateFraction to use
asApproximateFractionToEpsilon:? (asApproximateFraction has no senders into
base image)
Suggestions for a selector that would use self
asApproximateFractionToEpsilon: 1e-6 (less clumsy than e.g.
asUsefulApproximateFraction).
_,,,^..^,,,_
best, Eliot
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20180423/6bd678a5/attachment.html>
More information about the Squeak-dev
mailing list
|