<div dir="ltr">Hi All,<div><br></div><div>    asApproximateFraction isn't that useful.  It is based on asApproximateFractionAtOrder:, which gives you the best fraction it can find up to order.  e.g.</div><div><br></div><div><div>testContinuedFractions</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">     </span>self assert: (Float pi asApproximateFractionAtOrder: 1) = (22/7).</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">      </span>self assert: (Float pi asApproximateFractionAtOrder: 3) = (355/113)</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">    </span></div><div>Here's 32-bit Float 1/3:</div><div><div><div><br></div><div>((FloatArray new: 1) at: 1 put: 1/3; at: 1) 0.3333333432674408</div></div><div><br></div><div>((FloatArray new: 1) at: 1 put: 1/3; at: 1) asApproximateFraction (11184811/33554432)</div></div><div><br></div><div>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.</div><div><br></div><div>[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].</div><div><br></div><div>Let's get a feeling for orders; they're effectively negative powers of 10:</div><div><br></div><div><div>(1 to: 20) collect: [:order| | f |</div><div>{ order. (f := Float pi asApproximateFractionAtOrder: order). f asFloat. (f asFloat - Float pi) abs}]</div><div>{{1 . (22/7) . 3.142857142857143 . 0.0012644892673496777}.</div><div> {2 . (333/106) . 3.141509433962264 . 8.32196275291075e-5}.</div><div> {3 . (355/113) . 3.1415929203539825 . 2.667641894049666e-7}.</div><div> {4 . (103993/33102) . 3.1415926530119025 . 5.778906242426274e-10}.</div><div> {5 . (104348/33215) . 3.141592653921421 . 3.3162805834763276e-10}.</div><div> {6 . (208341/66317) . 3.1415926534674368 . 1.2235634727630895e-10}.</div><div> {7 . (312689/99532) . 3.1415926536189365 . 2.914335439641036e-11}.</div><div> {8 . (833719/265381) . 3.141592653581078 . 8.715250743307479e-12}.</div><div> {9 . (1146408/364913) . 3.141592653591404 . 1.6107115641261771e-12}.</div><div> {10 . (4272943/1360120) . 3.141592653589389 . 4.04121180963557e-13}.</div><div> {11 . (5419351/1725033) . 3.1415926535898153 . 2.220446049250313e-14}.</div><div> {12 . (80143857/25510582) . 3.1415926535897927 . 4.440892098500626e-16}.</div><div> {13 . (245850922/78256779) . 3.141592653589793 . 0.0}.</div><div> {14 . (817696623/260280919) . 3.141592653589793 . 0.0}.</div><div> {15 . (19052873251/6064717916) . 3.141592653589793 . 0.0}.</div><div> {16 . (19870569874/6324998835) . 3.141592653589793 . 0.0}.</div><div> {17 . (19870569874/6324998835) . 3.141592653589793 . 0.0}.</div><div> {18 . (19870569874/6324998835) . 3.141592653589793 . 0.0}.</div><div> {19 . (19870569874/6324998835) . 3.141592653589793 . 0.0}.</div><div> {20 . (19870569874/6324998835) . 3.141592653589793 . 0.0}}</div></div><div><br></div><div><br></div><div>More useful would be something like:</div><div><br></div><div><div>asApproximateFractionToEpsilon: epsilon</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">     </span>"Answer a Fraction approximating the receiver. This conversion uses the </div><div><span class="gmail-Apple-tab-span" style="white-space:pre"> </span>continued fraction method to approximate a floating point number."</div><div><br></div><div><span class="gmail-Apple-tab-span" style="white-space:pre">       </span>1 to: 12 do:</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">           </span>[:order| | fraction |</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">          </span> fraction := self asApproximateFractionAtOrder: order.</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">         </span> (fraction - self) abs <= epsilon ifTrue:</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">                   </span>[^fraction]].</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">  </span>^ self asApproximateFractionAtOrder: 0</div></div><div><br></div><div>and then instead of</div><div><br></div><div>asApproximateFraction</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">     </span>"Answer a Fraction approximating the receiver. This conversion uses the </div><div><span class="gmail-Apple-tab-span" style="white-space:pre"> </span>continued fraction method to approximate a floating point number."</div><div><br></div><div><span class="gmail-Apple-tab-span" style="white-space:pre">       </span>^ self asApproximateFractionAtOrder: 0</div><div><br></div><div>one could have</div><div><br></div><div><div>asApproximateFraction</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">   </span>"Answer a Fraction approximating the receiver. This conversion uses the </div><div><span class="gmail-Apple-tab-span" style="white-space:pre"> </span>continued fraction method to approximate a floating point number."</div><div><br></div><div><span class="gmail-Apple-tab-span" style="white-space:pre">       </span>^self asApproximateFractionToEpsilon: 1e-6</div></div><div><br></div><div>And hence</div><div><div><br></div><div>{ 0.0. 0.333. 0.5. 1.0. Float pi . ((FloatArray new: 1) at: 1 put: 1/3; at: 1) } collect:</div><div>    [:n| n asApproximateFractionToEpsilon: 1e-6]</div><div>{0 . (333/1000) . (1/2) . 1 . (355/113) . (1/3)}</div></div><div><br></div><div>Votes for or against changing asApproximateFraction to use asApproximateFractionToEpsilon:? (asApproximateFraction has no senders into base image)</div><div><br></div><div>Suggestions for a selector that would use self asApproximateFractionToEpsilon: 1e-6 (less clumsy than e.g. asUsefulApproximateFraction).</div><div><br></div><div class="gmail_signature"><div dir="ltr"><div><span style="font-size:small;border-collapse:separate"><div>_,,,^..^,,,_<br></div><div>best, Eliot</div></span></div></div></div>
</div></div>