<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-8012131534487039227</id><updated>2012-02-17T02:10:04.602+01:00</updated><title type='text'>Smallissimo</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://smallissimo.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8012131534487039227/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://smallissimo.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>nicolas cellier</name><uri>http://www.blogger.com/profile/13769333498003444630</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>16</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-8012131534487039227.post-4462617447227384374</id><published>2012-01-27T10:32:00.001+01:00</published><updated>2012-01-27T13:43:10.677+01:00</updated><title type='text'>Which fraction has these digits ?</title><content type='html'>&lt;table cellpadding="0" class="cf gJ" style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;tbody&gt;&lt;tr class="acZ"&gt;&lt;td class="gF gK"&gt;&lt;table cellpadding="0" class="cf ix"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;div class="lHQn1d" role="checkbox" style="outline: 0;" tabindex="-1"&gt;Sven Van Caekenberghe posted these nice example on Pharo mailing list:&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/td&gt;&lt;td class="gH"&gt;&lt;/td&gt;&lt;td class="gH"&gt;&lt;/td&gt;&lt;td class="gH acX" rowspan="2"&gt;&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr class="acZ"&gt;&lt;td colspan="3"&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;1/9801 asScaledDecimal: 200.&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;1/998001 asScaledDecimal: 3000.&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;This also works with:&lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;1/9801 printShowingDecimalPlaces: 200.&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;We could conjecture that &lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;1/99980001  asScaledDecimal: 40000&lt;/span&gt; should give a nice serie of digits too.&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;But if we want to form our own fraction, how can we construct it ?&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;Let us consider a fraction in interval ]0,1[&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;In "decimal" notation (I say decimal, but it is valid in any other base &lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;b&lt;/span&gt;), this fraction print in base &lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;b&lt;/span&gt; with a head composed of &lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;head size&lt;/span&gt; digits, and a repeated tail composed of &lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;tail size&lt;/span&gt; digits &lt;span style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;0.head_tail_tail_tail...&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;For example, &lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;b := 10&lt;/span&gt;, &lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;head := '123'&lt;/span&gt; and &lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;tail := '40'&lt;/span&gt;, will lead to &lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;(fraction asScaledDecimal: tail size * 3 + head size) = '0.123404040s9'&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;I once thought we could extend the syntax with such notation to denote infinite repetition:&lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;fraction := 0.123(45).&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;But we didn't, so what is the value of the &lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;fraction&lt;/span&gt;?&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;Let us work with numbers rather than strings:&lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;h := head ifEmpty: [0] ifNotEmpty: [Number readFrom: head base: b].&lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;t := tail ifEmpty: [0] ifNotEmpty: [Number readFrom: tail base: b].&lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;nh := head size.&lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;nt := tail size.&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;If we had infinite series (lazy one would be preferred), we could define:&lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;positiveIntegers := 1 to: Integer infinity. &lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;infiniteTail := (positiveIntegers collect: [:i | t / (b raisedTo: nt * i)]).&lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;fraction := (infiniteTail + h) / (b raisedTo: nh).&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;We have no such ready made infinity, nor lazy collections...&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;But even with such objects, we cannot evaluate this infiniteTail that easily. &lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;Really? If we shift it by tail size digits, we will obtain this number with same infiniteTail:&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;infiniteTail * (b raisedTo:&amp;nbsp; nt) = (t + infiniteTail).&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;From this property, it is easy to get:&lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;infiniteTail :=&amp;nbsp; t / ((b raisedTo: nt) - 1).&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;span style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;If we want a leading head, we simply have to shift above fraction:&lt;/span&gt;&lt;br /&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;fraction := (t / ((b raisedTo: nt) - 1) + h) / (b raisedTo: nh).&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;So, let us reconstruct Sven example:&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;| base tail |&lt;br /&gt;base := 10.&lt;br /&gt;tail := ((0 to: 97) , #(99) inject: '' writeStream into: [:s :n | n printOn: s base: base length: 2 padded: true. s]) contents.&lt;br /&gt;^(Number readFrom: tail base: base) / ((base raisedTo: tail size) - 1)&lt;/div&gt;&lt;div style="color: blue; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;-&amp;gt; 1/9801&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;Good. Now, this expression won't lead to nice fraction for any tail...&lt;/div&gt;&lt;span style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;If we want a fraction with numerator = 1, we need to find a divisor of the denominator 999....99.&lt;/span&gt; That's the nice thing with Sven example. I don't know how or where he found it, but I guess it'll be hard to be as elegant. Oh, maybe thanks to the extension to any base you can play with it too (you will need to implement &lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;printShowingDecimalPlaces:base:&lt;/span&gt;).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8012131534487039227-4462617447227384374?l=smallissimo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://smallissimo.blogspot.com/feeds/4462617447227384374/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://smallissimo.blogspot.com/2012/01/which-fraction-has-these-digits.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8012131534487039227/posts/default/4462617447227384374'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8012131534487039227/posts/default/4462617447227384374'/><link rel='alternate' type='text/html' href='http://smallissimo.blogspot.com/2012/01/which-fraction-has-these-digits.html' title='Which fraction has these digits ?'/><author><name>nicolas cellier</name><uri>http://www.blogger.com/profile/13769333498003444630</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8012131534487039227.post-6515600989187372483</id><published>2011-10-12T01:34:00.000+02:00</published><updated>2011-10-12T01:34:06.856+02:00</updated><title type='text'>About Complex in Squeak</title><content type='html'>&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;I noticed that &lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;Complex&lt;/span&gt; is present in Squeak trunk and not in Pharo, though not used. So I suggested to create a shared external package common to the two distributions in this &lt;a href="http://lists.squeakfoundation.org/pipermail/squeak-dev/2011-October/161827.html"&gt;thread&lt;/a&gt; with a few other technical questions. This can benefit to Pharo users, and since the base of interested people did not seem that large to me, it can't be bad to group forces.&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;I got quite a few answers, thanks to all participants.&amp;nbsp; Scattering my answers in many posts would lead to a lot of repetitions. Grouping the threads into a big string would be misbehaved. Though all subjects are tied together: this is a pretext for blogging. So here are my comments.&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;b&gt;Why &lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;Complex&lt;/span&gt; was removed from Pharo?&lt;/b&gt;&lt;br /&gt;I don't have a mailing list ref available, but I think it was on a path to a reduced image (not to say minimal). Complex is not used in a base image so it could be loaded on demand. It's the never ending discussions of whether constructing an image by assembling modules (packages?) or by stripping... Full vs Core...&lt;br /&gt;Another argument was that &lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;Complex&lt;/span&gt; implementation was not that good (&lt;i&gt;understand not universal &lt;/i&gt;- see below). So we should better let it leave the image and give a chance to alternate solutions (&lt;i&gt;driven by different trade off/paradigms&lt;/i&gt; - see below).&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;b&gt;Why Quaternion?&lt;/b&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;Quaternion&lt;/span&gt; are to SO3 what &lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;Complex&lt;/span&gt; are to &lt;a href="http://en.wikipedia.org/wiki/Special_orthogonal_group"&gt;SO2&lt;/a&gt;. They are often used in engineering, specially in robot arm control or spatial vehicle control because not suffering from &lt;a href="http://en.wikipedia.org/wiki/Euler_angles"&gt;Euler/Cardan angle singularities&lt;/a&gt;. They also replace trigonometric operations by algebraic ones (an advantage if there is no hard-wired trigonometry in FPU they just require sqrt). You can find Quaternion in &lt;a href="http://www.squeaksource.com/Quaternion.html"&gt;squeaksource&lt;/a&gt;.&lt;br /&gt;Octonions are generalization in spaces of dimension 4, so can be used in generalized relativity... I'm not aware of any Smalltalk implementation yet, maybe this niche is too narrow ;)&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;b&gt;Why I've suggested to rename &lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;Complex&lt;/span&gt; as &lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;ComplexNumber&lt;/span&gt;?&lt;/b&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;Because more expressive. I think it was also to match &lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;isComplexNumber&lt;/span&gt;. But, sure, we can dissociate the two...&lt;br /&gt;And also for stupid digression about an eventual distinction required by a symbolic Complex - apologize for the follow ups in the thread ;) .&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;b&gt;Why I suggested to implement &lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;isComplexNumber&lt;/span&gt; rather than &lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;isComplex&lt;/span&gt;?&lt;/b&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;Because the collisions and are not just imaginary ;) but happening for real as Juan reported.&lt;br /&gt;There is an issue opened in &lt;a href="http://bugs.squeak.org/view.php?id=2689"&gt;mantis&lt;/a&gt;.&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;b&gt;Why &lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;-1 sqrt&lt;/span&gt; raise an &lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;Error&lt;/span&gt; instead of answering one of the complex roots?&lt;/b&gt;&lt;br /&gt;This raises the question of the paradigm we want to use...&lt;br /&gt;It's very much like &lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;Fraction&lt;/span&gt; and &lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;Integer&lt;/span&gt;.&lt;br /&gt;In Smalltalk, every &lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;Fraction&lt;/span&gt; with a denominator = 1 is automatically reduced to an &lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;Integer&lt;/span&gt;. Thus we can consider that every &lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;Integer&lt;/span&gt; is a special kind of &lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;Fraction&lt;/span&gt; (with an implicit 1 denominator). It's thus logical to have &lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;Integer&lt;/span&gt; behave like a &lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;Fraction&lt;/span&gt; and respond to &lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;numerator&lt;/span&gt;, &lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;denominator&lt;/span&gt;, &lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;fractionPart&lt;/span&gt;, &lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;integerPart&lt;/span&gt; and even answer &lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;true&lt;/span&gt; to &lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;isFraction&lt;/span&gt; and  to &lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;selfasFraction&lt;/span&gt; (if it quacks like a duck... I made the changes recently in trunk).&lt;br /&gt;So we could consider the same with &lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;ComplexNumber&lt;/span&gt; and &lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;Number&lt;/span&gt;. Every &lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;Number&lt;/span&gt; is a &lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;Complex&lt;/span&gt; with a null imaginary part. Thus we could let &lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;Number&lt;/span&gt; behave like a &lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;Complex&lt;/span&gt; and extend its mathematical functions over complex domain (&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;-1 sqrt&lt;/span&gt;, &lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;2 arcCos&lt;/span&gt;, &lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;-1 argCosh&lt;/span&gt; etc...), and also let it answer to some &lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;Complex&lt;/span&gt; specific protocol like &lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;conjugated&lt;/span&gt; , &lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;imaginaryPart&lt;/span&gt;, &lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;realPart&lt;/span&gt;... In such paradigm, every &lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;Complex&lt;/span&gt; with a null imaginary part would be automatically reduced to a &lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;Number&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;This discussion already took place before...&lt;/b&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;Above generalization is quite nice. But unlike the case of &lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;Integer&lt;/span&gt; and &lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;Fraction&lt;/span&gt; we are changing the behaviour of &lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;sqrt&lt;/span&gt; and potentially breaking compatibility.&lt;br /&gt;Some applications do expect and require an &lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;Exception&lt;/span&gt;. If the &lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;Exception&lt;/span&gt; does not happen, then it will lead to delayed failure, or worse, incorrect results.&lt;br /&gt;One possible incorrect result would be to fill your bank account we imaginary €.&lt;br /&gt;Especially, knowing that &lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;1 i isNumber&lt;/span&gt; now answers &lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;true&lt;/span&gt;, defensive "type" checks that worked once are now by-passed, which worsen the situation. See digression below.&lt;br /&gt;&lt;br /&gt;The opposite point of view is to preserve compatibility and implement both behaviours.&lt;br /&gt;The solution adopted in Squeak is to let the programmer explicitly force a &lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;Number&lt;/span&gt; to behave as a &lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;Complex&lt;/span&gt; with &lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;-1 asComplex sqrt&lt;/span&gt;. In such case, the &lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;Complex&lt;/span&gt; must not automatically be reduced to a &lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;Number&lt;/span&gt; when its imaginary part is null. this way we can also chain complex behaviors, and that's what we currently get with &lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;2 asComplex sqrt arcSin&lt;/span&gt; we don't need to force a second time &lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;2 asComplex sqrt asComplex arcSin&lt;/span&gt;.&lt;br /&gt;Another solution would be to distinguish the selectors (like &lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;-1 sqrt&lt;/span&gt; versus &lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;-1 complexSqrt&lt;/span&gt;) and let &lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;Number&lt;/span&gt; and &lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;Complex&lt;/span&gt; respond to both protocols... But that's many mathematical functions to duplicate.&lt;br /&gt;&lt;br /&gt;I don't think Squeak solution is that bad, especially if we consider that &lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;Complex&lt;/span&gt; are rarely used. It is somehow very much like statically typed languages FORTRAN/C++ so some of you might not like it ;)&lt;br /&gt;The biggest grief is that we don't have static typing (not every receiver is literal), so we are forced to always send &lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;asComplex&lt;/span&gt; when in doubt. This can lead to scattering more such messages than manageable... That might happen in case of large usage of complex, but until now, nobody never complained.&lt;br /&gt;So I would not change implementation without very careful thoughts, and probably not change it at all in trunk. Because such change is a complete shift of paradigm with potentially nasty side effects for Complex-unaware-apps.&lt;br /&gt;If we want such change, I vote for removing &lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;Complex&lt;/span&gt; from image (the arguments already raised in Pharo).&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;b&gt;&lt;span style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;Why &lt;/span&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;1 i isNumber&lt;/span&gt;&lt;span style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt; answers &lt;/span&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;true&lt;/span&gt;&lt;span style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;?&lt;/span&gt;&lt;/b&gt;&lt;br style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;" /&gt;&lt;span style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;This was just to let this assertion work &lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;(0 i = 0) = (0 = 0 i)&lt;/span&gt;, &lt;/span&gt; &lt;a href="http://bugs.squeak.org/view.php?id=2688"&gt;originated here&lt;/a&gt;... &lt;span style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;OK, they don't behave the same, but still can be equal (&lt;a href="http://lists.squeakfoundation.org/pipermail/squeak-dev/2008-March/126494.html"&gt;or shall they not?&lt;/a&gt;).&lt;/span&gt;&lt;br style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;" /&gt;&lt;span style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;The second argument was that a &lt;/span&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;Complex&lt;/span&gt;&lt;span style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt; is a &lt;/span&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;Number&lt;/span&gt;&lt;span style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt; as the name doesn't tell - well &lt;/span&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;ComplexNumber&lt;/span&gt;&lt;span style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt; is more expressive, I warned you ;)&lt;/span&gt;&lt;br /&gt;&lt;br style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;" /&gt;&lt;b style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;Why I want to revert this change?&lt;/b&gt;&lt;br style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;" /&gt;&lt;span style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;1) This change did pierce now obsolete&lt;/span&gt; &lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;isNumber&lt;/span&gt;&lt;span style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt; defence... And expectations: belongs to R suddenly became belongs to C.&lt;/span&gt;&lt;br style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;" /&gt;&lt;span style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;If you analyze senders of &lt;/span&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;isNumber&lt;/span&gt;&lt;span style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;, just tell me how many are equipped to handle a &lt;/span&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;Complex&lt;/span&gt;&lt;span style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;?&lt;/span&gt; I tried it &lt;a href="http://lists.squeakfoundation.org/pipermail/squeak-dev/2008-March/126488.html"&gt;once&lt;/a&gt;.&lt;br style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;" /&gt;&lt;span style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;It's the same compatibility problem as &lt;/span&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;-1 sqrt&lt;/span&gt;&lt;span style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;...&lt;/span&gt;&lt;br style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;" /&gt;&lt;span style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;2) Since both &lt;/span&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;Number&lt;/span&gt; &lt;span style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;and&lt;/span&gt; &lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;Complex&lt;/span&gt;&lt;span style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt; answer true to &lt;/span&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;isNumber&lt;/span&gt;&lt;span style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;, then we logically shifted to the more general point of view that every &lt;/span&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;Number&lt;/span&gt;&lt;span style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt; is a &lt;/span&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;ComplexNumber&lt;/span&gt;&lt;span style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;.&lt;/span&gt;&lt;br style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;" /&gt;&lt;span style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;Unfortunately, this is not true, it does not match current paradigm. A&lt;/span&gt; &lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;Number&lt;/span&gt; &lt;span style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;does not behave like a &lt;/span&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;Complex&lt;/span&gt;&lt;span style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;, so&lt;/span&gt; &lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;isNumber&lt;/span&gt; &lt;span style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;distinction is now quite useless.&lt;/span&gt;&lt;br /&gt;&lt;br style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;" /&gt;&lt;span style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;The side effects are not imaginary ;), again this broke&lt;/span&gt; &lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;Quaternion&lt;/span&gt;&lt;span style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt; implementation for example. I had to commit a quick workaround&lt;/span&gt; &lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;(x isNumber and: [x isComplex not])&lt;span style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;but it's overkill, and just a smell that &lt;/span&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;isNumber&lt;/span&gt;&lt;span style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt; does not discriminate enough.&lt;/span&gt;&lt;br style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;" /&gt;&lt;span style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;We now badly need &lt;/span&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;isRealNumber&lt;/span&gt; &lt;span style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;- where real must be understood as not imaginary - see below.&lt;/span&gt;&lt;br style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;" /&gt;&lt;br style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;" /&gt;&lt;b&gt;&lt;span style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;Why reverting &lt;/span&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;Complex&amp;gt;&amp;gt;isNumber&lt;/span&gt; &lt;span style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;rather than creating &lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;Number&amp;gt;&amp;gt;isRealNumber&lt;/span&gt;?&lt;/span&gt;&lt;/b&gt;&lt;br style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;" /&gt;&lt;span style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;1) Please don't confuse &lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;isRealNumber&lt;/span&gt; and &lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;isFloat&lt;/span&gt;, that happens each time I open this can of worms. &lt;/span&gt;&lt;span style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;So I prefer to repeat myself, we have no representation of reals in Squeak, only of some special kinds of reals, &lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;Integer&lt;/span&gt;, &lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;Fraction&lt;/span&gt; and the degenerated inexact rounded fractions (I named &lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;Float&lt;/span&gt;).&lt;/span&gt;&lt;br style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;" /&gt;&lt;span style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;We could represent many others (like &lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;AlgebraicNumber&lt;/span&gt; in &lt;a href="http://www.dm.uba.ar/MathMorphs/"&gt;MathMorph&lt;/a&gt;).&lt;/span&gt;&lt;br style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;" /&gt;&lt;span style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;But real numbers are uncountable... See &lt;a href="http://en.wikipedia.org/wiki/Cardinality"&gt;http://en.wikipedia.org/wiki/Cardinality&lt;/a&gt;&lt;/span&gt;&lt;br style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;" /&gt;&lt;span style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;And we can only represent a countable subset of the real numbers... See &lt;a href="http://en.wikipedia.org/wiki/Computability"&gt;http://en.wikipedia.org/wiki/Computability&lt;/a&gt;.&lt;/span&gt;&lt;br style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;" /&gt;&lt;span style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;That's my first reason: this selector is confusing.&lt;/span&gt;&lt;br style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;" /&gt;&lt;span style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;2) With current implementation of &lt;/span&gt;&lt;span style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;/span&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;Complex&lt;/span&gt;&lt;span style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;/span&gt;&lt;span style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;, a &lt;/span&gt;&lt;span style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;/span&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;Complex&lt;/span&gt;&lt;span style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;/span&gt;&lt;span style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt; currently means two things:&lt;/span&gt;&lt;br style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;" /&gt;&lt;span style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;- if imaginary part is not null, then it is a real &lt;/span&gt;&lt;span style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;/span&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;ComplexNumber&lt;/span&gt;&lt;span style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;/span&gt;&lt;span style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;, well I mean unreal...&lt;/span&gt;&lt;br style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;" /&gt;&lt;span style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;- if imaginary part is null, then it is a real number that behaves like a &lt;/span&gt;&lt;span style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;/span&gt;&lt;span style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;/span&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;Complex&lt;/span&gt;&lt;span style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;/span&gt;&lt;span style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;/span&gt;&lt;br style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;" /&gt;&lt;span style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;Shall &lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;0 i isRealNumber&lt;/span&gt; answer &lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;true&lt;/span&gt;? The question will arise inevitably...&lt;/span&gt;&lt;br style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;" /&gt;&lt;span style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;That's my second reason: this selector is confusing.&lt;/span&gt;&lt;br style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;" /&gt;&lt;span style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;What we really seek is &lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;behavesLikeARealNumber&lt;/span&gt;. Ouch! I wish I never see such specialization in trunk ;)&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&lt;br style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;" /&gt;&lt;span style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;Ah, the good old time when&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;isComplex&lt;/span&gt; did mean &lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;isKindOf: Complex&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;isNumber&lt;/span&gt; did mean &lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;isKindOf: Number&lt;/span&gt; (what &lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;Complex&lt;/span&gt; are not)&lt;/span&gt;.&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;The alternative is to shift the paradigm and really let Number behave like Complex as told above, and assume all implications or reject the problem out the image... I have no easy solution handy. &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8012131534487039227-6515600989187372483?l=smallissimo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://smallissimo.blogspot.com/feeds/6515600989187372483/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://smallissimo.blogspot.com/2011/10/about-complex-in-squeak.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8012131534487039227/posts/default/6515600989187372483'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8012131534487039227/posts/default/6515600989187372483'/><link rel='alternate' type='text/html' href='http://smallissimo.blogspot.com/2011/10/about-complex-in-squeak.html' title='About Complex in Squeak'/><author><name>nicolas cellier</name><uri>http://www.blogger.com/profile/13769333498003444630</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8012131534487039227.post-4677019116592240993</id><published>2011-09-25T12:31:00.000+02:00</published><updated>2011-09-25T12:31:44.274+02:00</updated><title type='text'>Reviewing fraction asFloat</title><content type='html'>&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;After changing Integer&amp;gt;&amp;gt;asFloat, let's inspect Fraction&amp;gt;&amp;gt;asFloat. The spirit is quite simple: perform an Euclidean division after shifting the numerator or the denominator enough to obtain a certain precision in the quotient. The quotient will be the mantissa of the Float and the remainder are the truncated bits. Then come a dissertation on the conditions when to round upper or not. Let's see the code:&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;asFloat&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; "Answer a Float that closely approximates the value of the receiver.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; This implementation will answer the closest floating point number to&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; the receiver.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; It uses the IEEE 754 round to nearest even mode&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="background-color: yellow;"&gt;(can happen in case denominator is a power of two)&lt;/span&gt;"&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; | a b q r exponent floatExponent n ha hb hq q1 |&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; a := numerator abs.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; b := denominator abs.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ha := a highBit.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; hb := b highBit.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; "If both numerator and denominator are represented exactly in floating point number,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; then fastest thing to do is to use hardwired float division"&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; (ha &amp;lt; 54 and: [hb &amp;lt; 54]) ifTrue: [^numerator asFloat / denominator asFloat].&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; "Try and obtain a mantissa with 54 bits.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; First guess is rough, we might get one more bit &lt;span style="background-color: yellow;"&gt;or one less&lt;/span&gt;"&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; exponent := ha - hb - 54.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; exponent &amp;gt; 0&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ifTrue: [b := b bitShift: exponent]&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ifFalse: [a := a bitShift: exponent negated].&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; q := a quo: b.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; r := a - (q * b).&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; hq := q highBit.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; "check for gradual underflow, in which case we should use less bits"&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; floatExponent := exponent + hq - 1.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; n := floatExponent &amp;gt; -1023&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ifTrue: [54]&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ifFalse: [54 + floatExponent + 1022].&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; hq &amp;gt; n&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ifTrue: [exponent := exponent + hq - n.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; r := (q bitAnd: (1 bitShift: hq - n) - 1) * b + r.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; q := q bitShift: n - hq].&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; hq &amp;lt; n&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ifTrue: [exponent := exponent + hq - n.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; q1 := (r bitShift: n - hq) quo: b.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; q := (q bitShift: n - hq)&lt;span style="background-color: yellow;"&gt; bitAnd: &lt;/span&gt;q1.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; r := (r bitShift: n - hq) - (q1 * b)].&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; "check if we should round upward.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; The case of exact half (q bitAnd: 1) isZero not &amp;amp; (r isZero)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; will be handled by Integer&amp;gt;&amp;gt;asFloat"&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ((q bitAnd: 1) isZero or: [r isZero])&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ifFalse: [q := q + 1].&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ^ (self positive&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ifTrue: [q asFloat]&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ifFalse: [q = 0&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ifTrue: [Float negativeZero]&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ifFalse: [q asFloat negated]])&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; timesTwoPower: exponent&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;Let's review the three parts in yellow : first the comment (&lt;span style="background-color: yellow;"&gt;can happen in case denominator is a power of two&lt;/span&gt;) is obscure. It is supposed to explain that in case of tie, the algorithm will round to nearest even. The case of tie can only happen if the denominator is a power of two indeed, any other factor in the denominator will lead to an infinite series of digits and thus cannot produce a tie. But this information is not essential enough to be placed in the header. After all it is not essential at all.&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;The second part in yellow tells that the quotient could be &lt;span style="background-color: yellow;"&gt;one bit less&lt;/span&gt;. Let's see how false it is.&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;Let's write that b have hb bits, a ha bits and q hq bits, and the conditions of Euclidean division:&lt;/div&gt;&lt;ul&gt;&lt;li&gt;(1&amp;lt;&amp;lt; (ha-1)) &amp;lt;= a, a &amp;lt; (1 &amp;lt;&amp;lt; ha)&lt;/li&gt;&lt;li&gt;b &amp;lt; (1 &amp;lt;&amp;lt; hb)&lt;/li&gt;&lt;li&gt;q &amp;lt; (1 &amp;lt;&amp;lt; hq)&lt;/li&gt;&lt;li&gt;a=(b*q+r)&lt;/li&gt;&lt;li&gt;r &amp;lt; b&lt;/li&gt;&lt;/ul&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;From the last two relations we have a &amp;lt; (b*q+b), that is a &amp;lt; (b * (q+1)).&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;We still have, q + 1 &amp;lt;= (1 &amp;lt;&amp;lt; hq), thus b * (q+1)&lt;b&gt;&lt;/b&gt; &amp;lt; ((1 &amp;lt; hb) * (1 &amp;lt;&amp;lt; hq)), that is a &amp;lt; (1 &amp;lt; (hb+hq)).&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;But we also have (1 &amp;lt;&amp;lt; (ha - 1)) &amp;lt;= a, thus ha - 1 &amp;lt; (hb + hq).&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;This can be written hq &amp;gt; (ha - hb - 1), or hq &amp;gt;= (ha - hb). So the quotient will have at least ha - hb bits, maybe more, but never less.&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;The third part in yellow is trying to perform an addition with &lt;span style="background-color: yellow; color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;bitAnd:&lt;/span&gt; - ouch ! It could eventually be &lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;bitOr:&lt;/span&gt;, but why not simply writing &lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;q := (q bitShift: n - q) + q1&lt;/span&gt;...&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;Fortunately, this is the case of one bit less which can never happen.&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;There are other things to be enhanced. The numbers 54 and 1022 are kind of magical and use implicit knowledge that 54 = (Float precision + 1) and -1022 = Float emin, the minimum possible exponent of a Float before gradual underflow occurs.&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;So we should better re-write this code and:&lt;/div&gt;&lt;ul&gt;&lt;li&gt;change the heading comment;&lt;/li&gt;&lt;li&gt;remove the unreachable branch;&lt;/li&gt;&lt;li&gt;use the new floating point inquiry messages &lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;precision&lt;/span&gt; and &lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;emin&lt;/span&gt;;&lt;/li&gt;&lt;li&gt;name the mantissa &lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;mantissa&lt;/span&gt; rather than &lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;q&lt;/span&gt;;&lt;/li&gt;&lt;li&gt;avoid to compute the remainder &lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;r&lt;/span&gt;, but just check if it is zero or &lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;hasTruncatedBits&lt;/span&gt;;&lt;/li&gt;&lt;li&gt;let the floating point hardware handle the case of negative zero by itself&lt;br /&gt;(we just have to keep at least one bit in the mantissa).&lt;/li&gt;&lt;/ul&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;asFloat&lt;/span&gt;&lt;br style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;" /&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; "Answer a Float that closely approximates the value of the receiver.&lt;/span&gt;&lt;br style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;" /&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; This implementation will answer the closest floating point number to the receiver.&lt;/span&gt;&lt;br style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;" /&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; In case of a tie, it will use the IEEE 754 round to nearest even mode.&lt;/span&gt;&lt;br style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;" /&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; In case of overflow, it will answer +/- Float infinity."&lt;/span&gt;&lt;br style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;" /&gt;&lt;br style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;" /&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; | a b mantissa exponent hasTruncatedBits lostBit n ha hb hm |&lt;/span&gt;&lt;br style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;" /&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; a := numerator abs.&lt;/span&gt;&lt;br style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;" /&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; b := denominator.&amp;nbsp;&amp;nbsp;&amp;nbsp; "denominator is always positive"&lt;/span&gt;&lt;br style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;" /&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ha := a highBit.&lt;/span&gt;&lt;br style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;" /&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; hb := b highBit.&lt;/span&gt;&lt;br style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;" /&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;" /&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; "Number of bits to keep in mantissa plus one to handle rounding."&lt;/span&gt;&lt;br style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;" /&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; n := 1 + Float precision.&lt;/span&gt;&lt;br style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;" /&gt;&lt;br style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;" /&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; "If both numerator and denominator are represented exactly in floating point number,&lt;/span&gt;&lt;br style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;" /&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; then fastest thing to do is to use hardwired float division."&lt;/span&gt;&lt;br style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;" /&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; (ha &amp;lt; n and: [hb &amp;lt; n]) ifTrue: [^numerator asFloat / denominator asFloat].&lt;/span&gt;&lt;br style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;" /&gt;&lt;br style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;" /&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; "Shift the fraction by a power of two exponent so as to obtain a mantissa with n bits.&lt;/span&gt;&lt;br style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;" /&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; First guess is rough, the mantissa might have n+1 bits."&lt;/span&gt;&lt;br style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;" /&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; exponent := ha - hb - n.&lt;/span&gt;&lt;br style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;" /&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; exponent &amp;gt;= 0&lt;/span&gt;&lt;br style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;" /&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ifTrue: [b := b bitShift: exponent]&lt;/span&gt;&lt;br style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;" /&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ifFalse: [a := a bitShift: exponent negated].&lt;/span&gt;&lt;br style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;" /&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; mantissa := a quo: b.&lt;/span&gt;&lt;br style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;" /&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; hasTruncatedBits := a &amp;gt; (mantissa * b).&lt;/span&gt;&lt;br style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;" /&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; hm := mantissa highBit.&lt;/span&gt;&lt;br style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;" /&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;" /&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; "Check for gradual underflow, in which case the mantissa will loose bits.&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color: purple;"&gt;&lt;span style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;Keep at least 1 bit to let the underflow preserve the sign of zero.&lt;/span&gt;&lt;/span&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;"&lt;/span&gt;&lt;br style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;" /&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; lostBit := Float emin - (exponent + hm - 1).&lt;/span&gt;&lt;br style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;" /&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; lostBit &amp;gt; 0 ifTrue: [n := n - lostBit max: 1].&lt;/span&gt;&lt;br style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;" /&gt;&lt;br style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;" /&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; "Remove excess bits in the mantissa."&lt;/span&gt;&lt;br style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;" /&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; hm &amp;gt; n&lt;/span&gt;&lt;br style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;" /&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ifTrue:&lt;/span&gt;&lt;br style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;" /&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; [exponent := exponent + hm - n.&lt;/span&gt;&lt;br style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;" /&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; hasTruncatedBits := hasTruncatedBits or: [mantissa anyBitOfMagnitudeFrom: 1 to: hm - n].&lt;/span&gt;&lt;br style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;" /&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; mantissa := mantissa bitShift: n - hm].&lt;/span&gt;&lt;br style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;" /&gt;&lt;br style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;" /&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; "Check if mantissa must be rounded upward.&lt;/span&gt;&lt;br style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;" /&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; The case of tie (mantissa odd &amp;amp; hasTruncatedBits not)&lt;/span&gt;&lt;br style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;" /&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; will be handled by Integer&amp;gt;&amp;gt;asFloat."&lt;/span&gt;&lt;br style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;" /&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; (hasTruncatedBits and: [mantissa odd])&lt;/span&gt;&lt;br style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;" /&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ifTrue: [mantissa := mantissa + 1].&lt;/span&gt;&lt;br style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;" /&gt;&lt;br style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;" /&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ^ (self positive&lt;/span&gt;&lt;br style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;" /&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ifTrue: [mantissa asFloat]&lt;/span&gt;&lt;br style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;" /&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ifFalse: [mantissa asFloat negated])&lt;/span&gt;&lt;br style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;" /&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; timesTwoPower: exponent&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;That's it. No revolution, but I hope it's a bit clearer, and for the same price, a tiny bit more efficient.&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;I could also explain in this blog why it is better to use floating point division if both numerator and denominator can be converted asFloat exactly... Or why the mantissa loose bits in case of underflow... But, oh, I'm so lazy, ain't that boring enough?&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8012131534487039227-4677019116592240993?l=smallissimo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://smallissimo.blogspot.com/feeds/4677019116592240993/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://smallissimo.blogspot.com/2011/09/reviewing-fraction-asfloat.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8012131534487039227/posts/default/4677019116592240993'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8012131534487039227/posts/default/4677019116592240993'/><link rel='alternate' type='text/html' href='http://smallissimo.blogspot.com/2011/09/reviewing-fraction-asfloat.html' title='Reviewing fraction asFloat'/><author><name>nicolas cellier</name><uri>http://www.blogger.com/profile/13769333498003444630</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8012131534487039227.post-3244362148442883045</id><published>2011-09-22T00:09:00.000+02:00</published><updated>2011-09-22T00:09:16.049+02:00</updated><title type='text'>Clarifying and optimizing Integer&gt;&gt;asFloat</title><content type='html'>&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;I wanted to explain some notions about floating point and thought using &lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;Integer&amp;gt;&amp;gt;asFloat&lt;/span&gt; in Squeak as example. Unfortunately, I found the code was both not that clear and not that efficient and some of the comments were inaccurate (I can tell so without any diplomacy since it's my own production).&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;So I decided to change it once again.&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;First, let's see the comment. Three lines should be enough. Note that I didn't mention nearest Float, because in case of overflow we will answer &lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;Float infinity&lt;/span&gt;, while the nearest Float would be &lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;Float fmax&lt;/span&gt;.&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;Integer&amp;gt;&amp;gt;asFloat&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;"Answer a Float that best approximates the value of the receiver.&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;This algorithm is optimized to process only the significant digits of a LargeInteger.&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;And it does honour IEEE 754 round to nearest even mode in case of excess precision (see details below)."&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;Then, it might be useful to detail what round to nearest even means exactly. It's quite long and I'm not sure this belongs to the method or if it should just be replaced by a link... But it does also help understanding the code below.&lt;/div&gt;&lt;br /&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;"How numbers are rounded in IEEE 754 default rounding mode:&lt;/span&gt;&lt;br /&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;A shift is applied so that the highest 53 bits are placed before the floating point to form a mantissa.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;The trailing bits form the fraction part placed after the floating point.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;This fractional number must be rounded to the nearest integer.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;If fraction part is 2r0.1, exactly between two consecutive integers, there is a tie.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;The nearest even integer is chosen in this case.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;Examples (First 52bits of mantissa are omitted for brevity):&lt;/span&gt;&lt;br /&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;2r0.00001 is rounded downward to 2r0&lt;/span&gt;&lt;br /&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;2r1.00001 is rounded downward to 2r1&lt;/span&gt;&lt;br /&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;2r0.1 is a tie and rounded to 2r0 (nearest even)&lt;/span&gt;&lt;br /&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;2r1.1 is a tie and rounded to 2r10 (nearest even)&lt;/span&gt;&lt;br /&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;2r0.10001 is rounded upward to 2r1&lt;/span&gt;&lt;br /&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;2r1.10001 is rounded upward to 2r10&lt;/span&gt;&lt;br /&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;Thus, if the next bit after floating point is 0, the mantissa is left unchanged.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;If next bit after floating point is 1, an odd mantissa is always rounded upper.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;An even mantissa is rounded upper only if the fraction part is not a tie."&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;Then we can come with a cleaner implementation by just naming the variables more explicitly to fit the comments:&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;| mantissa shift sum excess mask trailingBits nextBitIsSet tie |&lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;mantissa := self abs.&lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;"Check how many bits excess the maximum precision of a Float mantissa."&lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;excess := mantissa highBit - Float precision.&lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;excess &amp;gt; 0&lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;ifTrue:&lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;["Remove the excess bits"&lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;mask := (1 bitShift: excess) - 1.&lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;trailingBits := mantissa bitAnd: mask.&lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;"trailingBits isZero ifFalse: [Inexact signal]."&lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;mantissa := mantissa bitShift: excess negated.&lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;shift := excess.&lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;"But care to honour IEEE 754 round to nearest even mode."&lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;nextBitIsSet := trailingBits highBit = excess.&lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;(nextBitIsSet and: [mantissa odd or:&lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;[tie := trailingBits isPowerOfTwo.&lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;tie not]])&lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;ifTrue: [mantissa := mantissa + 1]]&lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;ifFalse: [shift := 0].&lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;"Now that mantissa has no more excess precision, the following floating point operations will be exact."&lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;sum := 0.0.&lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;1 to: mantissa digitLength do:&lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;[:byteIndex | &lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&lt;/span&gt;sum := sum + &lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&lt;/span&gt;((mantissa digitAt: byteIndex) asFloat timesTwoPower: shift)&lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;shift := shift + 8].&lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;^ self positive&lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;ifTrue: [sum]&lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;ifFalse: [sum negated]&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;Note that in this case, the rounding is performed entirely in Smalltalk and the algorithm will round to nearest even whatever the hardware rounding mode is, because all successive floating point operations will be exact.&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;The hardware inexact flag thus won't be set. We could replace this by a soft &lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;Inexact signal&lt;/span&gt;, but this is commented out because we don't care of and don't have such exception in Smalltalk until now. It's just a Smalltalkish comment.&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;But this code still performs many bit operations on LargeIntegers in case of excess precision. We could try alternatives that won't produce intermediate LargeIntegers.&lt;/div&gt;&lt;div style="color: purple; font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;span style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;excess &amp;gt; 0&lt;/div&gt;&lt;div style="color: purple; font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;span style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;ifTrue:&lt;/div&gt;&lt;div style="color: purple; font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;span style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;["Take care to honour IEEE 754 round to nearest even mode."&lt;/div&gt;&lt;div style="color: purple; font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;span style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;mustRoundUpper := (mantissa bitAt: excess) &amp;gt; 0 "The bit after floating point is set"&lt;/div&gt;&lt;div style="color: purple; font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;span style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;and: [(mantissa bitAt: 1 + excess) &amp;gt; 0 "The mantissa is odd"&lt;/div&gt;&lt;div style="color: purple; font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;span style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;or: [excess &amp;gt; 1 and: [self anyBitOfMagnitudeFrom: 1 to: excess - 1 "This is not a tie"]]].&lt;/div&gt;&lt;div style="color: purple; font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;span style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;"Remove the excess bits"&lt;/div&gt;&lt;div style="color: purple; font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;span style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;mantissa := mantissa bitShift: excess negated.&lt;/div&gt;&lt;div style="color: purple; font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;span style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;shift := excess.&lt;/div&gt;&lt;div style="color: purple; font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;span style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;mustRoundUpper ifTrue: [mantissa := mantissa + 1]]&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;But see how we must assist the code with many comments... Not that good. And not that faster...&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;We can still write more efficient code: we just have to let the hardware perform the rounding by itself. In effect, if we just add one excess bit, we are sure that there will be at most one inexact operation, and thus that we won't cumulate round off errors. But in this case, it is necessary to explain in preamble:&lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; "Algorihm details:&lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Floating point hardware will correctly handle the rounding by itself with a single inexact operation if mantissa has one excess bit of precision.&lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Except in the last case when extra bits are present after an even mantissa, we must round upper by ourselves.&lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Note 1: the inexact flag in floating point hardware must not be trusted because it won't take into account the bits we truncated by ourselves.&lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Note 2: the floating point hardware is presumed configured in default rounding mode."&lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; | mantissa shift sum excess |&lt;/span&gt;&lt;br /&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;mantissa := self abs.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;"Check how many bits excess the maximum precision of a Float mantissa."&lt;/span&gt;&lt;br /&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;excess := mantissa highBit - Float precision.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;excess &amp;gt; 1&lt;/span&gt;&lt;br /&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;ifTrue:&lt;/span&gt;&lt;br /&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;["Remove the excess bits but one"&lt;/span&gt;&lt;br /&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;mantissa := mantissa bitShift: 1 - excess.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;shift := excess - 1.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;"Handle the case of extra bits truncated after an even mantissa."&lt;/span&gt;&lt;br /&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;((mantissa bitAnd: 2r11) = 2r01 and: [self anyBitOfMagnitudeFrom: 1 to: shift])&lt;/span&gt;&lt;br /&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;ifTrue: [mantissa := mantissa + 1]]&lt;/span&gt;&lt;br /&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;ifFalse: [shift := 0].&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;"Now that mantissa has at most 1 excess bit of precision, let floating point operations perform the final rounding."&lt;/span&gt;&lt;br /&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;sum := 0.0.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;1 to: mantissa digitLength do:&lt;/span&gt;&lt;br /&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;[:byteIndex | &lt;/span&gt;&lt;br /&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;sum := sum + ((mantissa digitAt: byteIndex) asFloat timesTwoPower: shift).&lt;/span&gt;&lt;br /&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;shift := shift + 8].&lt;/span&gt;&lt;br /&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;^ self positive&lt;/span&gt;&lt;br /&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;ifTrue: [sum]&lt;/span&gt;&lt;br /&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;ifFalse: [sum negated]&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&lt;span style="color: black; font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;This&amp;nbsp; is shorter and faster, and a bit more fragile because now depending on hardware settings... But we never change these settings in Smalltalk, so we don't mind. Eventually, we could also come with a version that will always honour hardware rounding mode in the future - only if we can control it from within Smalltalk. The most annoying thing is that we trade some didactic properties now hidden into hardware black box. Now I must decide wether to commit immediately or wait for further comments...&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8012131534487039227-3244362148442883045?l=smallissimo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://smallissimo.blogspot.com/feeds/3244362148442883045/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://smallissimo.blogspot.com/2011/09/clarifying-and-optimizing.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8012131534487039227/posts/default/3244362148442883045'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8012131534487039227/posts/default/3244362148442883045'/><link rel='alternate' type='text/html' href='http://smallissimo.blogspot.com/2011/09/clarifying-and-optimizing.html' title='Clarifying and optimizing Integer&gt;&gt;asFloat'/><author><name>nicolas cellier</name><uri>http://www.blogger.com/profile/13769333498003444630</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8012131534487039227.post-4934497239657695324</id><published>2011-08-30T02:35:00.000+02:00</published><updated>2011-08-30T02:35:05.408+02:00</updated><title type='text'>ArbitraryPrecisionFloat</title><content type='html'>After Smallapack, I decided to open another google code project for another already existing cross-dialect package - &lt;a href="https://code.google.com/p/arbitrary-precision-float"&gt;ArbitraryPrecisionFloat&lt;/a&gt;. This time, no FFI complications, the package is 100% "pure" Smalltalk (it does not mean 100% beautiful, I can't judge myself but severly). I will try to update the &lt;a href="http://en.wikipedia.org/wiki/Arbitrary_precision"&gt;Wikipedia page&lt;/a&gt; because my favourite language deserves a bit more visibility.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8012131534487039227-4934497239657695324?l=smallissimo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://smallissimo.blogspot.com/feeds/4934497239657695324/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://smallissimo.blogspot.com/2011/08/arbitraryprecisionfloat.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8012131534487039227/posts/default/4934497239657695324'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8012131534487039227/posts/default/4934497239657695324'/><link rel='alternate' type='text/html' href='http://smallissimo.blogspot.com/2011/08/arbitraryprecisionfloat.html' title='ArbitraryPrecisionFloat'/><author><name>nicolas cellier</name><uri>http://www.blogger.com/profile/13769333498003444630</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8012131534487039227.post-3583599043602211384</id><published>2011-08-26T00:26:00.001+02:00</published><updated>2011-08-26T18:01:34.171+02:00</updated><title type='text'>Smallapack on google code</title><content type='html'>Finally I decided to gather notes about Smallapack on google code&lt;a href="https://code.google.com/p/smallapack"&gt; https://code.google.com/p/smallapack&lt;/a&gt;&lt;br /&gt;The site is very young and does not contain much material yet, but it will be completed with installation notes, code snippets and a few insights on design.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8012131534487039227-3583599043602211384?l=smallissimo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://smallissimo.blogspot.com/feeds/3583599043602211384/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://smallissimo.blogspot.com/2011/08/smallapack-on-google-code.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8012131534487039227/posts/default/3583599043602211384'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8012131534487039227/posts/default/3583599043602211384'/><link rel='alternate' type='text/html' href='http://smallissimo.blogspot.com/2011/08/smallapack-on-google-code.html' title='Smallapack on google code'/><author><name>nicolas cellier</name><uri>http://www.blogger.com/profile/13769333498003444630</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8012131534487039227.post-3643154678037217872</id><published>2011-08-23T22:14:00.002+02:00</published><updated>2011-08-23T22:43:36.108+02:00</updated><title type='text'>Smallapack progress on Squeak</title><content type='html'>&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;This post is about &lt;b style="color: #073763;"&gt;Smallapack&lt;/b&gt;, a Smalltalk interface to &lt;a href="http://www.netlib.org/lapack"&gt;LAPACK&lt;/a&gt;.&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;Smallapack deals with basic linear algebra (the BLAS) or more ellaborated linear algebra, like solving least squares problem, eigenvalues problems, singular values decompositions etc... (LAPACK).&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;It enables Smalltalk to deal efficiently with number crunching by delegating these operations to specially optimized external libraries, at the express condition that operations can be arrayed (a lot like Matlab interpreter for example).&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;Smallapack implementation was working for a long time in Cincom VW and Dolphin dialects, but I never was able to have it running reliably on Squeak. Until yesterday night, when I learned the stupid little detail that caused that mess:&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;b style="color: #073763;"&gt;Modern C ABI expect an 8 byte alignment for double * data&lt;/b&gt; (especially for some library optimized thru SSE2 instructions or such).&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;Squeak has a super feature that enables passing a ByteArray allocated in Object memory rather than an ExternalAddress pointing to some memory allocated on external heap. I abused this feature, because heap management requires malloc and free, and why bother with so much basic tasks, when I can just let the garbage collector take care of Object memory... Unfortunately, this excess of trust was my mistake:&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;b style="color: #073763;"&gt;Squeak objects are 4 bytes aligned&lt;/b&gt;, at least on all 32 bit VMs available to date.&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;Hence, some function calls will randomly crash the VM with a protection fault (OSX gdb says &lt;span style="font-size: x-small;"&gt;&lt;b&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;EXC_BAD_ACCESS&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;). The garbage collector has a license to allocate on 4 byte boundary or to rellocate on 4 bytes boundary at any time, and thus there is not much we can do about it. Eliot told me that a new garbage collector with proper 8 byte alignment  was in his plans, but not soon, Once more, I will depend on the  tremendous amount of work this guy put in Smalltalk, but who doesn't?  Viva Miranda!&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;So my bug was happening by example with cblas_dgemv on Mac OSX veclib if the matrix is transposed, and by extension with any LAPACK function calling a transposing DGEMV... &lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;b style="color: #073763;"&gt;GOOD NEWS!&lt;/b&gt; Once discovered last night, the bug was quickly fixed this evening, it was just a matter of redefining two methods (&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;arrayPointer&lt;/span&gt;) so that they transfer the data in external heap (&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;storeInCSpace&lt;/span&gt;) before answering the pointer object...&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;u&gt;&lt;b&gt;&lt;span style="color: red;"&gt;IN THE INTERIM, FOR THOSE WHO USE Squeak FFI: BEWARE&lt;/span&gt;&lt;/b&gt;&lt;/u&gt;.&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;It is very dangerous to use a &lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;(ByteArray new: byteSize)&lt;/span&gt; as a memory for holding a table of double and passing it as argument to an external procedure... Some external procedures will tolerate a 4 bytes alignment, some won't... You should always prefer an &lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;(ExternalAddress gcallocate: byteSize)&lt;/span&gt; for passing a double *. By virtue of libc &lt;span style="font-size: x-small;"&gt;&lt;b&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;malloc()&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;, the &lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;ExternalAddress&lt;/span&gt; shall always contain a correctly aligned pointer.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8012131534487039227-3643154678037217872?l=smallissimo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://smallissimo.blogspot.com/feeds/3643154678037217872/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://smallissimo.blogspot.com/2011/08/smallapack-progress-on-squeak.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8012131534487039227/posts/default/3643154678037217872'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8012131534487039227/posts/default/3643154678037217872'/><link rel='alternate' type='text/html' href='http://smallissimo.blogspot.com/2011/08/smallapack-progress-on-squeak.html' title='Smallapack progress on Squeak'/><author><name>nicolas cellier</name><uri>http://www.blogger.com/profile/13769333498003444630</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8012131534487039227.post-587124423999406004</id><published>2011-08-16T23:58:00.000+02:00</published><updated>2011-08-16T23:58:26.890+02:00</updated><title type='text'>Funny design decision</title><content type='html'>&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;span style="font-size: small;"&gt;I write this for sharing but also for reminding me later: if you ever have to develop in FORTRAN there is a gfortran option that &lt;u&gt;SHOULD&lt;/u&gt; be your companion&lt;/span&gt;&lt;br /&gt;&lt;pre class="smallexample"&gt;-finit-real=snan&lt;/pre&gt;&lt;span style="font-size: small;"&gt;With this option, every real variable will automatically be initialized with a signalling nan, and your program should stop when it will incorrectly use the variable. &lt;/span&gt;&lt;span style="font-size: small;"&gt;The SUN FORTRAN compiler did have such option for long, but it takes time to reach this original quality.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: small;"&gt;And indeed, g77 did not provide such option but only a poor man's&lt;/span&gt;&lt;br /&gt;&lt;pre class="smallexample"&gt;-finit-local-zero&lt;/pre&gt;&lt;span style="font-size: small;"&gt;The former helps you &lt;b&gt;finding&lt;/b&gt; your bugs while the later is more to help you &lt;b&gt;hiding&lt;/b&gt; your bugs. &lt;b style="color: blue;"&gt;&lt;i&gt;What a funny design decision...&lt;/i&gt;&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: small;"&gt;I had to code array/matrix crunching code for tight loops and wanted to use Lapack/Blas for that. &lt;/span&gt;And I wanted the latest version with bug corrections. However, I discovered that release 3.3 of Lapack now contains FORTRAN 90 specific instructions. &lt;span style="font-size: small;"&gt;Of course, there are plenty sources of errors in FORTRAN 77 that have been addressed by FORTRAN 90... The ones that would have been most useful to me today are:&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-size: small;"&gt;verification of subroutine interface &lt;/span&gt;signature (number of arguments, types and input/output intent) &lt;/li&gt;&lt;li&gt;passing an object (with number of dimensions, bounds and stride) rather than just the address of the raw array storage.&lt;/li&gt;&lt;/ul&gt;The former was traditionally&amp;nbsp; verified by 3rd party analyzers (forcheck, ftnchek).&lt;br /&gt;But the later is a real improvement. There was a compiler option that did perform runtime checks&lt;br /&gt;&lt;pre class="smallexample"&gt;-fbounds-check&lt;/pre&gt;But it was more a joke than something useful because it uses the declared bounds, not the really allocated ones.&lt;br /&gt;Unfortunately, if you want to profit by these features, your code has to adhere to FORTRAN 90 interface definitions. Lapack does not. It was written in FORTRAN 77 for historical reasons and I suspect it remains like this both for economical reasons and efficiency reasons (like passing an address is just faster than passing an array and going thru runtime checks). Since the FORTRAN 90 interface declarations wrappers to Lapack are not even kept up to date, there is not much to gain by using FORTRAN 90...&amp;nbsp; That just prevents me to use g77, f2c, or ftnchek for no good reason (except a recursive routine), so I thought, &lt;i&gt;&lt;b style="color: blue;"&gt;what a funny design decision...&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: small;"&gt;Finally, I went thru edit/compile/print (gdb will not debug FORTRAN that easily, especially if you want to inspect multi-dimensional arrays, you first have to debug the debugger). A&lt;/span&gt;&lt;span style="font-size: small;"&gt;s usual, some error was on my test code, while I was stupidly focusing on the more complex tested code. A&lt;/span&gt;&lt;span style="font-size: small;"&gt;t the end of the day I had to admit that most of the time lost was in:&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-size: small;"&gt;translating &lt;/span&gt;&lt;span style="font-size: small;"&gt; a few f90-ism back to f77 (to please g77);&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size: small;"&gt;and not testing uninitialized variables (no such option in g77).&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-size: small;"&gt;All this, just because I decided to use g77... &lt;b style="color: blue;"&gt;&lt;i&gt;What a funny design decision!&lt;/i&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;span style="font-size: small;"&gt;And next time, I &lt;u&gt;SHALL&lt;/u&gt; remember that ftnchek &lt;u&gt;SHOULD&lt;/u&gt; always be the natural companion of such funny decisions.&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;span style="font-size: small;"&gt;Well, we are very far from Smalltalk. Our debugger rarely has to be debugged and our instance and temp variables are initialized to nil, &lt;/span&gt;&lt;span style="font-size: small;"&gt;so design quality was again ahead and&lt;/span&gt;&lt;span style="font-size: small;"&gt; the subject is closed. But would Smalltalk perform your number crunching? Not mine. Not even, C, C++, or FORTRAN will. That's why the Blas were invented. I eventually have Smallapack, a functioning interface to Blas/Lapack in Visualworks, but it's not up to date either (Lapack 3.0...) and debugging bare bone allocation problems through an additional DLLCC/VM layer would not help. What I would need (and maybe program one day in Smalltalk) is a FORTRAN interpreter with all the necessary bound checks...&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8012131534487039227-587124423999406004?l=smallissimo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://smallissimo.blogspot.com/feeds/587124423999406004/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://smallissimo.blogspot.com/2011/08/funny-design-decision.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8012131534487039227/posts/default/587124423999406004'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8012131534487039227/posts/default/587124423999406004'/><link rel='alternate' type='text/html' href='http://smallissimo.blogspot.com/2011/08/funny-design-decision.html' title='Funny design decision'/><author><name>nicolas cellier</name><uri>http://www.blogger.com/profile/13769333498003444630</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8012131534487039227.post-7698726711223131866</id><published>2011-08-04T14:53:00.000+02:00</published><updated>2011-08-04T14:53:42.940+02:00</updated><title type='text'>Lazy initialization of Shared Variable Bindings</title><content type='html'>&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;One problem we encounter with package management in Squeak/Pharo, but also in other Smalltalk dialects is the initialisation of shared variables.&lt;/div&gt;&lt;br style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;" /&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;Generally a class initialization message is defined like this:&lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;MyClass class&amp;gt;&amp;gt;initialize&lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; MyShared1 := SomeOtherClass new.&lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; self snipLotOfMoreCode&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;And by convention, this &lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;initialize&lt;/span&gt; method is executed at package load.&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;But what if the initialization of a package require another package which is not yet loaded (for example containing &lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;SomeOtherClass&lt;/span&gt; or less trivially, containing a message sent during the initialization process).&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;One work around often encountered&amp;nbsp; is to use a message indirection coupled with a lazy initialization to access the shared variable value, like this:&lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;MyClass class&amp;gt;&amp;gt;someSharedInfo&lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp; &amp;nbsp; ^SomeSharedInfo ifNil: [self initializeSomeSharedInfo]&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;But why putting pressure on coder when the system could do it by itself ?&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;The idea is to create a new class for holding uninitialized variable bindings or value and associate an initialization method to be executed when first access will be attempted.&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;Associating an initialization method could be performed through use of pragmas, for example:&lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;MyClass class&amp;gt;&amp;gt;initializeSomeSharedVariables&lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; #&amp;lt;initialize&amp;gt;&lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; MyShared1 := 5.&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; MyShared2 := #yourself.&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;In Smalltalk, a shared variable is a binding (an &lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;Association&lt;/span&gt;) with the variable name as key (generally a Symbol) and a value (the value of the variable). The Smalltalk Compiler arrange so that binding is unique across all method accessing the variable, thus the value can effectively be shared.&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;Now, what happens if we access &lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;MyShared1&lt;/span&gt; ? In Smalltalk, shared variable are generally not accessed by sending &lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;value&lt;/span&gt;/&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;value:&lt;/span&gt; messages to the binding. Instead, the compiler produces a byte code that directly fetch the second inst.var. for reading and another similar byte code for writing the value.&amp;nbsp;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;But this can be controlled in Squeak/Pharo by a compiler hook: just define your own binding class and two methods:&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt; &lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;YourOwnSharedVariableBinding&amp;gt;&amp;gt;isSpecialReadBinding&lt;/span&gt;&lt;br style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;" /&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; "Return true if this variable binding is read protected, e.g., should not be accessed primitively but rather by sending #value messages"&lt;/span&gt;&lt;br style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;" /&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ^true&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;YourOwnSharedVariableBinding&amp;gt;&amp;gt;isSpecialWriteBinding&lt;/span&gt;&lt;br style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;" /&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; "Return true if this variable binding is write protected, e.g., should not be accessed primitively but rather by sending #value: messages"&lt;/span&gt;&lt;br style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;" /&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ^true&lt;/span&gt; &lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;So we now have many options to implement a lazy initialization...&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;u&gt;&lt;b&gt;Solution 1)&lt;/b&gt;&lt;/u&gt; instead of initializing value with nil, create an UnitializedSharedValue class pointing to the binding and an initialization message to be performed&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;And implement &lt;b&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;doesNotUnderstand:&lt;/span&gt;&lt;/b&gt; like this&lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;ProtoObject subclass: #UnitializedSharedValue&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; instanceVariableNames: 'binding initializer'&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; classVariableNames: ''&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; poolDictionaries: ''&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; category: 'Utility' &lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;setInitializer: anEvaluator&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;"Set the evaluator responsible of initializing variable value.&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;anEvaluator should understand the message value."&lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; initializer :=&amp;nbsp; anEvaluator&lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;setBinding: aVariableBinding&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; binding :=&amp;nbsp; aVariableBinding&lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&lt;b&gt;doesNotUnderstand: aMessage&lt;/b&gt;&lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; initializer&lt;/b&gt;&lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ifNil:&lt;/b&gt;&lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [binding error: 'This variable binding does not have any known initializer'.&lt;/b&gt;&lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ^nil].&lt;/b&gt;&lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; initializer value.&lt;/b&gt;&lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; binding value == self&lt;/b&gt;&lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ifTrue:&lt;/b&gt;&lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [binding error: 'The initializer failed to initialize this binding'.&lt;/b&gt;&lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ^nil].&lt;/b&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;b&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp; &amp;nbsp; ^binding value perform: aMessage selector withArguments: aMessage arguments&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;The problem with this kind of trick is that it is hard to catch all message sends (in Squeak/Pharo, &lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;class&lt;/span&gt; is not a true message send for example). And if you catch them, you then can't debug easily, because the debugger uses message sends too.&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;u&gt;&lt;b&gt;Solution 2)&lt;/b&gt;&lt;/u&gt; create &lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;AutoInitializedSharedVariableBinding&lt;/span&gt; that is Special Read Binding&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;and use an indirection to access the &lt;b style="color: purple;"&gt;&lt;span style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;value&lt;/span&gt;&lt;/b&gt;:&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;  &lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;LookupKey subclass: #AutoInitializedSharedVariableBinding&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; instanceVariableNames: 'value undefined initializer'&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; classVariableNames: ''&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; poolDictionaries: ''&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; category: 'Collections-Support'&lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;initialize&lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; value := undefined := Object new.&lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;isVariableBinding&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ^true&lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;isSpecialReadBinding&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ^true&lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;setInitializer: anEvaluator&lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; initializer :=&amp;nbsp; anEvaluator&lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&lt;b&gt;value&lt;/b&gt;&lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ^value == undefined&lt;/b&gt;&lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ifTrue: [value]&lt;/b&gt;&lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ifFalse: [self initializeValue]&lt;/b&gt;&lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;initializeValue&lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; initializer&lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ifNil:&lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [self error: 'This variable binding does not have any known initializer'.&lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ^nil].&lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; initializer value.&lt;br /&gt;&lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; value == undefined&lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ifTrue:&lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [self error: 'The initializer failed to initialize this binding'.&lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ^nil].&lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp; &amp;nbsp; ^value&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;This will cost an indirection (the #value send) and one test at each access. Not worse than manual lazy initialization we saw first.&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;u&gt;&lt;b&gt;Solution 3)&lt;/b&gt;&lt;/u&gt; avoid the value == undefined test by using a &lt;b style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;become:&lt;/b&gt; trick. There will still be a value/value: indirection cost though, so it might not be worth the complications...&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt; &lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;LookupKey subclass: #UninitializedVariableBinding&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; instanceVariableNames: 'value'&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; classVariableNames: ''&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; poolDictionaries: ''&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; category: 'Collections-Support'&lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;key: aKey value: anEvaluator &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; key := aKey.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; value := anEvaluator &lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;setInitializer: anEvaluator&lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; value :=&amp;nbsp; anEvaluator&lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;isVariableBinding&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ^true&lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;isSpecialReadBinding&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ^true&lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;isSpecialWriteBinding&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ^true&lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt; value&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ^value&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ifNil: [UnitializedVariableException signal]&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ifNotNil: [self value: value value]&lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&lt;b&gt;value: anObject&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; self become: (InitializedVariableBinding key: key value: anObject).&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ^anObject&lt;/b&gt;&lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;  &lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;LookupKey subclass: #InitializedVariableBinding&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;instanceVariableNames: 'value'&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;classVariableNames: ''&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;poolDictionaries: ''&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;category: 'Collections-Support'&lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;key: aKey value: anObject&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; key := aKey.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; value := anObject&lt;br /&gt;&lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&lt;b&gt;setInitializer: anEvaluator&lt;/b&gt;&lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; self become: (UninitializedVariableBinding key: key value: anEvaluator).&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;^self&lt;/b&gt;&lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;isVariableBinding&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ^true&lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;isSpecialReadBinding&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ^true&lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;isSpecialWriteBinding&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ^true&lt;br /&gt;&lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt; value&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ^value&lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;value: anObject&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ^value := anObject&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;Note the return in last method so that we can chain &lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;MyShared1 := MyShared2 := someValue&lt;/span&gt;...&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;u&gt;&lt;b&gt;Solution 4)&lt;/b&gt;&lt;/u&gt; like in Cincom VisualWorks, let all &lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;SharedVariableBinding&lt;/span&gt; carry their own initialization code (which is like a clean block). But this does not solve the initialization order problems and this requires tools support (and also source code management support for storing/retrieving/executing the code associated to the shared variable binding).&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;u&gt;&lt;b&gt;The pragma handling common to all solutions: &lt;/b&gt;&lt;/u&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;Just create this class&lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;InstructionClient subclass: #SharedInitializationFinder&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; instanceVariableNames: 'usedBeforeDefined initializedBindingsByFetchingValue initializedBindingsBySendingValue stack stackPerPC pc'&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; classVariableNames: ''&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; poolDictionaries: ''&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; category: 'Utility'`&lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&lt;span style="color: black; font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;With these class methods: &lt;/span&gt;&lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;initialize&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; "SharedInitializationFinder initialize."&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; self registerForEvents&lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;registerForEvents&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; SystemChangeNotifier uniqueInstance noMoreNotificationsFor: self.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; SystemChangeNotifier uniqueInstance notify: self ofAllSystemChangesUsing: #initializeEvent:.&lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;scanMethod: aCompiledMethod&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; "Answer with a list of variable bindings initialized by aCompiledMethod via sending #value: message."&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ^self new scanMethod: aCompiledMethod&lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;initializeEvent: anEvent&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; "Check if this system event defines or removes an automatic initialization."&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; | aClass aSelector method |&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; (anEvent itemKind = SystemChangeNotifier classKind and: [anEvent isRemoved])&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ifTrue: ["We should track initializations bound to this class..."].&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; anEvent itemKind = SystemChangeNotifier methodKind ifTrue: [&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; aClass := anEvent itemClass.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; aClass isMeta ifFalse: [^self]. "ignore instance methods"&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; aClass := aClass theNonMetaClass.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; aSelector := anEvent itemSelector.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; aSelector numArgs &amp;gt; 0 ifTrue: [^self]. "ignore methods with arguments"&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; (anEvent isRemoved) ifTrue: [&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; "We should track initializations bound to this class and method..."].&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; (anEvent isAdded or: [anEvent isModified]) ifTrue: [&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; method := anEvent item.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; method pragmas do: [:pragma |&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; | shared |&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; pragma keyword == #initialize ifTrue: [&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; shared := self scanMethod: method.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; shared do: [:binding | binding setInitializer: (MessageSend receiver: aClass selector: aSelector)]]]]].&lt;br /&gt;&amp;nbsp;&lt;/div&gt;&lt;div style="color: black; font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;On instance side, let the class process the bytecodes decoding (most are omitted), the most important being:&lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;initializeBindings&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; usedBeforeDefined := Set new.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; initializedBindingsByFetchingValue := Set new.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; initializedBindingsBySendingValue := Set new. &lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;initializedBindingsByFetchingValue&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; "Answer with the list of variable bindings being initialized by target CompiledMethod by directly storing into value."&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ^initializedBindingsByFetchingValue&lt;br /&gt;initializedBindingsBySendingValue&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; "Answer with the list of variable bindings being initialized by target CompiledMethod by directly sending value: message."&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ^initializedBindingsBySendingValue&lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;pushLiteralVariable: anAssociation&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; "Push Contents Of anAssociation On Top Of Stack bytecode."&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; stack addLast: anAssociation &lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;popIntoLiteralVariable: anAssociation &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; "Remove Top Of Stack And Store Into Literal Variable bytecode."&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; initializedBindingsByFetchingValue add: anAssociation.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; stack removeLast&lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;send: aSelector super: supered numArgs: numberArguments&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; | theReceiver |&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1 to: numberArguments do: [:i | stack removeLast].&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; theReceiver := stack removeLast.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; theReceiver ifNotNil: [&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; aSelector == #value ifTrue: [usedBeforeDefined add: theReceiver].&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; aSelector == #value: ifTrue: ["Protect against trivial infinite loops..."&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; (usedBeforeDefined includes: theReceiver)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ifFalse: [initializedBindingsBySendingValue add: theReceiver]]].&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; stack addLast: nil&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;scanMethod: method&lt;/span&gt;&lt;br style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;" /&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; | scanner end |&lt;/span&gt;&lt;br style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;" /&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; self initializePC.&lt;/span&gt;&lt;br style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;" /&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; scanner := InstructionStream on: method.&lt;/span&gt;&lt;br style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;" /&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; end := method endPC.&lt;/span&gt;&lt;br style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;" /&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; [(pc := scanner pc) &amp;lt;= end] whileTrue:&lt;/span&gt;&lt;br style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;" /&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; [stackPerPC at: pc ifPresent: [:restoredStack | stack := restoredStack].&lt;/span&gt;&lt;br style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;" /&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; scanner interpretNextInstructionFor: self].&lt;/span&gt;&lt;br style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;" /&gt;&lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ^self initializedBindingsBySendingValue&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;Last, we need to define a hook, such that any binding could become an uninitialized or auto initialized variable binding, for example, solution 3) would be:&lt;/div&gt;&lt;div style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;LookUpKey&amp;gt;&amp;gt;setInitializer: anEvaluator&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; "Set the evaluator responsible of initializing variable value.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; anEvaluator should understand the message value."&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; self become: (UninitializedVariableBinding key: key value: anEvaluator).&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ^self&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;The nice thing with above hook is that each time you change the initialization method, the variables will be reset by the &lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;setInitializer:&lt;/span&gt; mechanism. No more manual doIt : &lt;span style="color: purple; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;self initializeThisOrThat&lt;/span&gt;.&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;Of course, there are more things to handle before getting a fully functioning framework:&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;1) what if you remove an initializer method/class ?&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;2) what if you define two or more initializer methods ?&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;Especially, if you define a second initialization method then, oops, remove it, the variables should switch back to the first initialization...&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;3) detecting unchanged initialization method and avoiding unecessary re-initialization would be smart.&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt; &lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;But these are boring little details... (where the devil is hidden as you may know).&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8012131534487039227-7698726711223131866?l=smallissimo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://smallissimo.blogspot.com/feeds/7698726711223131866/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://smallissimo.blogspot.com/2011/08/lazy-initialization-of-shared-variable.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8012131534487039227/posts/default/7698726711223131866'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8012131534487039227/posts/default/7698726711223131866'/><link rel='alternate' type='text/html' href='http://smallissimo.blogspot.com/2011/08/lazy-initialization-of-shared-variable.html' title='Lazy initialization of Shared Variable Bindings'/><author><name>nicolas cellier</name><uri>http://www.blogger.com/profile/13769333498003444630</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8012131534487039227.post-4187147574293812652</id><published>2011-07-12T14:15:00.000+02:00</published><updated>2011-07-12T14:15:41.800+02:00</updated><title type='text'>Xtreams version of the optimized prime factors factorial</title><content type='html'>&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;I now want to use Xtreams on the optimized version of &lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;primeFactorFactorial&lt;/span&gt;:&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;optimizedPrimeFactorFactorialViaXtreams&lt;/div&gt;&lt;div style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; | primes uniqPowers highestPower prevPower primeGroup primesGroupedByPower bitIterator terms numGroupsEstimate |&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;Forming a generator of primes:&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; primes := [:out | self orLessAllPrimesDo: [:prime | out put: prime ] ] reading.&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;Removing first prime, because we will handle power of 2 by a final bitShift:&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; primes get.&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;Forming two collections, the group of primes having the same power, and their unique powers.&lt;/div&gt;&lt;br /&gt;&lt;div style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;numGroupsEstimate := 1 &amp;lt;&amp;lt; (self highBit // 2).&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;uniqPowers := (Array new: numGroupsEstimate) writing.&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;primesGroupedByPower := (Array new: numGroupsEstimate) writing.&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;prevPower := nil.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; primeGroup := Array new writing.&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;primes do: [:p |&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;| primePower |&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;primePower := self - (self sumDigitsInBase: p) // (p - 1).&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;prevPower&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;ifNil:&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;[uniqPowers put: primePower.&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;prevPower := highestPower := primePower]&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;ifNotNil: [prevPower ~= (prevPower := primePower)&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;ifTrue:&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;[primesGroupedByPower put: primeGroup conclusion reading.&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;uniqPowers put: primePower.&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; primeGroup := Array new writing]].&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; primeGroup put: p].&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;primesGroupedByPower put: primeGroup conclusion reading.&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;primesGroupedByPower := primesGroupedByPower conclusion reading.&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;uniqPowers := uniqPowers conclusion reading.&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;Note that this part is not lazy, because I later want to reuse these two collections several times. This part is not the most elegant I came up with. It is much like using a &lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;(ending:) slicing&lt;/span&gt; sequence, but &lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;ending:&lt;/span&gt; is not splitting the groups where I want to...&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;Another option would be to count the number of equal powers, and use that in a &lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;(limiting:) slicing&lt;/span&gt; sequence, but &lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;limiting:&lt;/span&gt; is not taking a block argument...&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;Forming an iterator on the powers bits:&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; bitIterator := [:out |&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;| bitProbe |&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;bitProbe := 1.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;[ bitProbe &amp;lt;= highestPower ]&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;whileTrue:&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;[out put: bitProbe.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;bitProbe := bitProbe bitShift: 1 ] ] reading.&lt;/span&gt;&lt;br /&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;For each bit, grouping primes having the bit set in their associated power, and raise the product of this group to the power of corresponding bit:&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; terms := bitIterator collect: [:bit |&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; primesGroupedByPower += 0.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; uniqPowers += 0.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (primesGroupedByPower selecting: [:pp |&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; pp += 0.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; (uniqPowers get bitAnd: bit) ~= 0])&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; stitching rest karatsubaProduct raisedToInteger: bit].&lt;/span&gt;&lt;br /&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;Note that &lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;stitching&lt;/span&gt; is concatenating the substreams into a single stream, while &lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;+= 0&lt;/span&gt; is resetting the streams at the beginning.&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;Performing the product of products and shifting to account the power of 2:&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;^terms karatsubaProduct bitShift: self - self bitCount&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;There is still an operation I didn't Xtreamize, the &lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;karatsubaProduct&lt;/span&gt;. It consists in a recursive split. Not sure how to do it...&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;Now let us see if timing is decent:&lt;/div&gt;&lt;div style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;Smalltalk garbageCollect.&lt;br /&gt;[50000 optimizedPrimeFactorFactorialViaXtreams] timeToRun&lt;/div&gt;&lt;div style="color: blue; font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;b&gt;-&amp;gt; 1321&lt;/b&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;span style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;Approximately the same as the non Xtreams version (+4%). That's pretty good.&lt;/span&gt;&lt;br /&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;But this version has a tricky bug: &lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;stitching&lt;/span&gt; is raising &lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;Incomplete&lt;/span&gt; if there is no substream, and this happens for some numbers. For example,&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;9 optimizedPrimeFactorFactorialViaXtreams&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&lt;/span&gt;produces the groups &lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;((3) (5 7))&lt;/span&gt; with the powers &lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;(4 1)&lt;/span&gt;. When the &lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;bitIterator&lt;/span&gt; generator is evaluating with &lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;bit = 2&lt;/span&gt;, there is no group having a power with this bit set, &lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;Incomplete&lt;/span&gt; is raised by &lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;stitching&lt;/span&gt;, and caught &lt;span style="color: black; font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;by the generator&lt;/span&gt; which closes the stream without the final term &lt;span style="color: #4c1130;"&gt;(3 raisedTo: 4)&lt;/span&gt;. Thus it returns a wrong result... Ouch! That's one reason for I dislike Exceptions.&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;My single test on a huge number did not fail, and I only discovered the bug with the generator free version:&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;optimizedPrimeFactorFactorialViaXtreams2&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; | uniqPowers highestPower prevPower primeGroup primesGroupedByPower terms numGroupsEstimate |&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; numGroupsEstimate := 1 &amp;lt;&amp;lt; (self highBit &amp;gt;&amp;gt; 1).&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; uniqPowers := (Array new: numGroupsEstimate) writing.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; primesGroupedByPower := (Array new: numGroupsEstimate) writing.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; prevPower := nil.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; highestPower := 0.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; primeGroup := Array new writing.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Integer primesUpTo: self + 1 do: [:p | p = 2 ifFalse: [&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; | primePower |&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; primePower := self - (self sumDigitsInBase: p) // (p - 1).&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; prevPower&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ifNil:&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; [uniqPowers put: primePower.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; prevPower := highestPower := primePower]&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ifNotNil: [prevPower ~= (prevPower := primePower)&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ifTrue:&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; [primesGroupedByPower put: primeGroup conclusion reading.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; uniqPowers put: primePower.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; primeGroup := Array new writing]].&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; primeGroup put: p]].&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; primesGroupedByPower put: primeGroup conclusion reading.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; primesGroupedByPower := primesGroupedByPower conclusion reading.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; uniqPowers := uniqPowers conclusion reading.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; terms := (1 to: highestPower highBit) collect: [:bit |&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; primesGroupedByPower += 0.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; uniqPowers += 0.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; [| product |&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; product := (primesGroupedByPower selecting: [:pp |&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; pp += 0.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; (uniqPowers get bitAt: bit) ~= 0])&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; stitching rest karatsubaProduct.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; 1 to: bit - 1 do: [:i | product := product squared].&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; product] on: Incomplete do: [1]].&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ^terms karatsubaProduct bitShift: self - self bitCount&lt;/span&gt;&lt;br /&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;Overall, I find Xtreams powerfull, far more than Smalltalk Stream. But there are still things lacking. For example, the grouping was not obvious. The stitching of empty streams was surprising. I might need a readingStitching that works with an empty stream.&lt;br /&gt;&lt;br /&gt;Xtreams is interesting both for its functional like aspects and for its potential use in parallelism, a lot like &lt;a href="http://cag.lcs.mit.edu/commit/papers/06/gordon-asplos06-slides.pdf%20"&gt;this&lt;/a&gt;. From this later point of view, I find it easy to pipe serial operations with Xtreams in case of a single assembly line. It also seems possible to fork processing for each element when they are independent (this is data parallelism - and could be applied for performing &lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;karatsubaProduct&lt;/span&gt; of each term in above example, and thus get a very efficient parallel version of factorial).&lt;br /&gt;On the other hand, having two parallel assembly lines does not seem that easy. There is a duplicating: operation that should allow such parallel streams, but it necessarily uses a writeStream. I'd like the assembly chain to be as easy as:&lt;/div&gt;&lt;div style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&lt;br /&gt;fork := [:in :out1 :out2 | | item | item := in get. out1 put: item. out2 put: item] forking.&lt;br /&gt;line1 := [:in :out | out put: in get op1] filtering. &lt;/div&gt;&lt;div style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;line2 := [:in :out | out put: in get op2] filtering. &lt;/div&gt;&lt;div style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;join := [:in1 :in2 :out | out put: (in1 get op3: in2 get)] joining.&lt;br /&gt;factory := generator | fork | (line1 &amp;amp; line2) | join. &lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;Funily, I used unix pipe | to denote serial and ampersand &amp;amp; to denote parallel, but I find the contrary more natural: || makes me think of parallelism, and &amp;amp; of sequencing. Just a point of view... &lt;br /&gt;&lt;br /&gt;From above point of view, the differences between read and write streams seems a bit arbitrary. Filters are inherently both. The Generator pattern could be used to turn any WriteStream (push) into a ReadStream (pull), but it's current implementation has potential dead lock conditions. But wait, it's possible I missed some features, or miss-used some others, Xtreams is evolving rapidly. There is a new &lt;a href="http://mlucassmith.tumblr.com/post/7511322455/polycephaly-finds-new-home-in-xtreams-grid"&gt;post&lt;/a&gt; about using Xtreams with parallel VM, I have to inquire a bit more!&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8012131534487039227-4187147574293812652?l=smallissimo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://smallissimo.blogspot.com/feeds/4187147574293812652/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://smallissimo.blogspot.com/2011/07/xtreams-version-of-optimized-prime.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8012131534487039227/posts/default/4187147574293812652'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8012131534487039227/posts/default/4187147574293812652'/><link rel='alternate' type='text/html' href='http://smallissimo.blogspot.com/2011/07/xtreams-version-of-optimized-prime.html' title='Xtreams version of the optimized prime factors factorial'/><author><name>nicolas cellier</name><uri>http://www.blogger.com/profile/13769333498003444630</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8012131534487039227.post-2580301147022091805</id><published>2011-07-09T02:14:00.000+02:00</published><updated>2011-07-09T02:14:23.151+02:00</updated><title type='text'>Testing new Xtreams generators</title><content type='html'>&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;So, I upgraded Squeak port of &lt;a href="http://code.google.com/p/xtreams/"&gt;Xtreams&lt;/a&gt;, and just tested it on the &lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;primeFactorFactorial&lt;/span&gt; example:&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;primeFactorFactorialViaXtreams&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; | primes powers factorial |&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; primes := [:out | Integer primesUpTo: self + 1 do: [:prime | out put: prime ] ] reading.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; powers := primes collecting: [:p | p raisedToInteger: self - (self sumDigitsInBase: p) // (p - 1)].&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; factorial := powers injecting: 1 into: [:product :power | product * power].&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ^(factorial positioning buffer: (XTRingBuffer new: 1 class: Array))&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; -= 1;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; get&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;This looks good, except the final sentence which is not simple to read to my taste, remember it just extract the last element...&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;Now let's see performance:&lt;/div&gt;&lt;div style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;Smalltalk garbageCollect.&lt;/span&gt;&lt;br style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;" /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;Time millisecondsToRun: [10000 primeFactorFactorial].&lt;/span&gt;&lt;br /&gt;&lt;b style="color: blue;"&gt;-&amp;gt; 297&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;Smalltalk garbageCollect.&lt;/span&gt;&lt;br style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;" /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;Time millisecondsToRun: [10000 primeFactorFactorialViaGeneratorAndXtream].&lt;/span&gt;&lt;br /&gt;&lt;b style="color: blue;"&gt;-&amp;gt; 390&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;Smalltalk garbageCollect.&lt;/span&gt;&lt;br style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;" /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;Time millisecondsToRun: [10000 primeFactorFactorialViaXtreams].&lt;/span&gt;&lt;br /&gt;&lt;b style="color: blue;"&gt;-&amp;gt; 945&lt;/b&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;Huh?&lt;/div&gt;&lt;div style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;MessageTally spyOn: [10000 primeFactorFactorialViaXtreams].&lt;/div&gt;&lt;div style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;- 820 tallies, 822 msec.&lt;/span&gt;&lt;br style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;" /&gt;&lt;br style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;" /&gt;&lt;span style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;**Tree**&lt;/span&gt;&lt;br style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;" /&gt;&lt;span style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;--------------------------------&lt;/span&gt;&lt;br style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;" /&gt;&lt;span style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;Process: other processes&lt;/span&gt;&lt;br style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;" /&gt;&lt;span style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;--------------------------------&lt;/span&gt;&lt;br style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;" /&gt;&lt;span style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;47.8% {393ms} WeakArray class&amp;gt;&amp;gt;finalizationProcess&lt;/span&gt;&lt;br style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;" /&gt;&lt;span style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp; 39.4% {324ms} WeakFinalizationList class&amp;gt;&amp;gt;initTestPair&lt;/span&gt;&lt;br style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;" /&gt;&lt;span style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; |39.4% {324ms} Object class(Behavior)&amp;gt;&amp;gt;new&lt;/span&gt;&lt;br style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;" /&gt;&lt;span style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp; 8.4% {69ms} primitives&lt;/span&gt;&lt;br style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;" /&gt;&lt;span style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;17.0% {140ms} EventSensor&amp;gt;&amp;gt;eventTickler&lt;/span&gt;&lt;br style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;" /&gt;&lt;span style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp; 17.0% {140ms} Delay&amp;gt;&amp;gt;wait&lt;/span&gt;&lt;br style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;" /&gt;&lt;span style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;--------------------------------&lt;/span&gt;&lt;br style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;" /&gt;&lt;span style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;Process: (40s) 86874: nil&lt;/span&gt;&lt;br style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;" /&gt;&lt;span style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;--------------------------------&lt;/span&gt;&lt;br style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;" /&gt;&lt;span style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;34.0% {279ms} XTPositionReadStream(XTReadStream)&amp;gt;&amp;gt;-=&lt;/span&gt;&lt;br style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;" /&gt;&lt;span style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp; 34.0% {279ms} XTPositionReadStream&amp;gt;&amp;gt;length&lt;/span&gt;&lt;br style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;" /&gt;&lt;span style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 34.0% {279ms} XTPositionReadStream&amp;gt;&amp;gt;++&lt;/span&gt;&lt;br style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;" /&gt;&lt;span style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 34.0% {279ms} XTPositionReadStream(XTReadStream)&amp;gt;&amp;gt;++&lt;/span&gt;&lt;br style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;" /&gt;&lt;span style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 34.0% {279ms} XTPositionReadStream&amp;gt;&amp;gt;read:into:at:&lt;/span&gt;&lt;br style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;" /&gt;&lt;span style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 34.0% {279ms} XTCollectReadStream&amp;gt;&amp;gt;read:into:at:&lt;/span&gt;&lt;br style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;" /&gt;&lt;span style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 34.0% {279ms} XTCollectReadStream&amp;gt;&amp;gt;directRead:into:at:&lt;/span&gt;&lt;br style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;" /&gt;&lt;br style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;" /&gt;&lt;span style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;**Leaves**&lt;/span&gt;&lt;br style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;" /&gt;&lt;span style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;39.4% {324ms} Object class(Behavior)&amp;gt;&amp;gt;new&lt;/span&gt;&lt;br style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;" /&gt;&lt;span style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;34.0% {279ms} XTCollectReadStream&amp;gt;&amp;gt;directRead:into:at:&lt;/span&gt;&lt;br style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;" /&gt;&lt;span style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;17.0% {140ms} Delay&amp;gt;&amp;gt;wait&lt;/span&gt;&lt;br style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;" /&gt;&lt;span style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;8.4% {69ms} WeakArray class&amp;gt;&amp;gt;finalizationProcess&lt;/span&gt;&lt;br style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;" /&gt;&lt;br style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;" /&gt;&lt;span style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;**Memory**&lt;/span&gt;&lt;br style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;" /&gt;&lt;span style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; old&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; -1,959,252 bytes&lt;/span&gt;&lt;br style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;" /&gt;&lt;span style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; young&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; +1,059,496 bytes&lt;/span&gt;&lt;br style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;" /&gt;&lt;span style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; used&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; -899,756 bytes&lt;/span&gt;&lt;br style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;" /&gt;&lt;span style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; free&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; -1,059,496 bytes&lt;/span&gt;&lt;br style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;" /&gt;&lt;br style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;" /&gt;&lt;span style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;**GCs**&lt;/span&gt;&lt;br style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;" /&gt;&lt;span style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; full&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; 3 totalling 455ms (55.0% uptime), avg 152.0ms&lt;/span&gt;&lt;br style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;" /&gt;&lt;span style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; incr&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; 19 totalling 65ms (8.0% uptime), avg 3.0ms&lt;/span&gt;&lt;br style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;" /&gt;&lt;span style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; tenures&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; 0&lt;/span&gt;&lt;br style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;" /&gt;&lt;span style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; root table&amp;nbsp;&amp;nbsp;&amp;nbsp; 0 overflows&lt;/span&gt;&lt;/span&gt; &lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;span style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;MessageTally&lt;/span&gt; is not reliable with COG VM, but clearly, only one third of execution time is spent in the &lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;primeFactorFactorialViaXtreams&lt;/span&gt;. It seems like something is wrong with this image, and implementing the generator via interprocess synchronisation did favour those CPU hijackers!&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8012131534487039227-2580301147022091805?l=smallissimo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://smallissimo.blogspot.com/feeds/2580301147022091805/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://smallissimo.blogspot.com/2011/07/testing-new-xtreams-generators.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8012131534487039227/posts/default/2580301147022091805'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8012131534487039227/posts/default/2580301147022091805'/><link rel='alternate' type='text/html' href='http://smallissimo.blogspot.com/2011/07/testing-new-xtreams-generators.html' title='Testing new Xtreams generators'/><author><name>nicolas cellier</name><uri>http://www.blogger.com/profile/13769333498003444630</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8012131534487039227.post-2618612731949529748</id><published>2011-07-06T06:00:00.106+02:00</published><updated>2011-07-07T01:18:14.124+02:00</updated><title type='text'>Optimizing the product of prime powers</title><content type='html'>&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;Remember how we generated the factorial from the product of its prime factors?&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;Let's try and optimize the product.&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;First trick is to use a &lt;a href="http://blogten.blogspot.com/2008/07/mr-karatsuba.html"&gt;Karatsuba multiplication&lt;/a&gt;, because multiplication is the major contributor in execution time.&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;The Squeak variant takes care to evaluate Karatsuba only on well balanced operands, and replace the recursion by an iteration if not well balanced: &lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;LargePositiveInteger&amp;gt;&amp;gt;karatsubaTimes: anInteger&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; "eventually use Karatsuba algorithm to perform the multiplication"&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; | half xHigh xLow yHigh yLow low high mid xLen yLen |&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; (anInteger isLargeEnoughForKaratsuba&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; and: [self isLargeEnoughForKaratsuba]) ifFalse: [^self timesInteger: anInteger].&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; "Check if length ratio is more than 2, and engage a loop&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; to operate on integers with well balanced lengths.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Note that we only add overhead at this level,&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; but we hope to gain in lower level recursion"&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; (xLen := self digitLength) &amp;gt;= (yLen := anInteger digitLength)&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ifTrue: [(half := xLen bitShift: -1) &amp;gt;= yLen&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ifTrue: [^(0 to: xLen by: yLen) detectSum: [:yShift |&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ((self copyDigitsFrom: yShift + 1 to: yShift + yLen)&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; karatsubaTimes: anInteger)&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; bitShift: 8 * yShift]]]&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ifFalse: [(half := yLen bitShift: -1) &amp;gt;= xLen&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ifTrue: [^(0 to: yLen by: xLen) detectSum: [:xShift |&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; (self karatsubaTimes:&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; (anInteger copyDigitsFrom: xShift + 1 to: xShift + xLen))&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; bitShift: 8 * xShift]]].&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; "At this point, lengths are well balanced, divide each integer in two halves"&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; xHigh := self bitShift: -8 * half.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; xLow := self lowestNDigits: half.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; yHigh := anInteger bitShift: -8 * half.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; yLow := anInteger lowestNDigits: half.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; "Karatsuba trick: perform with 3 multiplications instead of 4"&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; low := xLow karatsubaTimes: yLow.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; high := xHigh karatsubaTimes: yHigh.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; mid := (xHigh + xLow karatsubaTimes: yHigh + yLow) - (low + high).&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; "Sum the parts of decomposition"&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ^low + (mid bitShift: 8*half) + (high bitShift: 16*half)&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;With a bit of tuning for the COG VM:&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;LargePositiveInteger&amp;gt;&amp;gt;isLargeEnoughForKaratsuba&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ^self digitLength &amp;gt;= 160&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&lt;/div&gt;&lt;span style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;SmallInteger is not large enough for Karatsuba and falls back to regular multiplication *, we omit the code here.&lt;/span&gt;&lt;span style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;The &lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;copyDigitsFrom:to:&lt;/span&gt; and &lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;lowestNDigits:&lt;/span&gt; are just using a primitive for splitting a &lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;LargePositiveInteger&lt;/span&gt;, they are omitted too.&lt;/span&gt;&lt;br /&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;We'd also better optimize &lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;squared&lt;/span&gt; which is a simple case:&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;LargePositiveInteger&amp;gt;&amp;gt;squared&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; "Eventually use a divide and conquer algorithm to perform the multiplication"&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; | half xHigh xLow low high mid |&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; self isLargeEnoughForKaratsuba ifFalse: [^self * self].&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; "Divide digits in two halves"&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; half := self digitLength bitShift: -1.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; xHigh := self bitShift: -8 * half.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; xLow := self lowestNDigits: half.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; "Use Karatsuba"&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; low := xLow squared.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; high := xHigh squared.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; mid := xLow karatsubaTimes: xHigh.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; "Sum the parts of decomposition"&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ^low + (mid bitShift: 8*half+1) + (high bitShift: 16*half)&lt;/div&gt;&lt;br /&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;Then use &lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;squared&lt;/span&gt; in &lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;raisedToInteger:&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;Number&amp;gt;&amp;gt;raisedToInteger: anInteger&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; | bitProbe result |&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; anInteger negative ifTrue: [^(self raisedToInteger: anInteger negated) reciprocal].&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; bitProbe := 1 bitShift: anInteger highBit - 1.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; result := self class one.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp; [&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; (anInteger bitAnd: bitProbe) = 0 ifFalse: [result := result * self].&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; bitProbe := bitProbe bitShift: -1.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; bitProbe &amp;gt; 0 ]&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; whileTrue: [result := result squared].&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ^result&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;We have a reasonable implementation for Karatsuba, but we cannot use a naïve:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;Integer&amp;gt;&amp;gt;karatsubaPrimeFactorFactorial&lt;/span&gt;&lt;br style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;" /&gt; &lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; "Recompose the factorial from the prime factors, knowing the power of each prime."&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; ^((Integer primesUpTo: self + 1) collect: [:p |&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; p raisedToInteger: self - (self sumDigitsInBase: p) // (p - 1)]) karatsubaProduct&lt;/span&gt; &lt;br /&gt;&lt;br /&gt;Collection&amp;gt;&amp;gt;karatsubaProduct&lt;/div&gt;&lt;div style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ^self inject: 1 into: [:product :element | product karatsubaTimes: element]&lt;/div&gt;&lt;div style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&lt;/span&gt;Karatsuba is just a drag in this case because we always multiply a large integer with a small one. The only advantage comes from using &lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;squared&lt;/span&gt; in &lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;raisedToInteger&lt;/span&gt;:, and instead of 19136ms, we get:&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;Smalltalk garbageCollect.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;Time millisecondsToRun: [1 to: 3000 do: [:x | x karatsubaPrimeFactorFactorial]].&lt;/span&gt;&lt;br /&gt;&lt;b style="color: blue;"&gt;-&amp;gt;&amp;nbsp; 18408 18503&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;So the second trick is essential: evaluate the product of terms in a divide and conquer fashion, dividing the numbers to multiply in two groups and recursively:&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;SequenceableCollection&amp;gt;&amp;gt;karatsubaProduct&lt;/div&gt;&lt;div style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; "Compute the product of self elements, using Karatsuba multiplication"&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; self isEmpty ifTrue: [^1].&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ^self karatsubaProductFrom: 1 to: self size by: 1&lt;/div&gt;&lt;div style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;SequenceableCollection&amp;gt;&amp;gt;karatsubaProductFrom: startIndex to: stopIndex by: inc&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; | nextInc nextIndex |&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; (nextIndex := startIndex + inc) &amp;gt; stopIndex ifTrue: [^self at: startIndex].&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; nextInc := inc * 2.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ^(self karatsubaProductFrom: startIndex to: stopIndex by: nextInc) karatsubaTimes:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (self karatsubaProductFrom: nextIndex to: stopIndex by: nextInc)&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;Smalltalk garbageCollect.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;Time millisecondsToRun: [1 to: 3000 do: [:x | x karatsubaPrimeFactorFactorial]].&lt;/span&gt;&lt;br /&gt;&lt;b style="color: blue;"&gt;-&amp;gt; 12627 12539&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Better, but there is room toward the prime swing variant which performs the job in less than &lt;b&gt;&lt;span style="color: blue;"&gt;7000ms&lt;/span&gt;&lt;/b&gt;. Let's adapt our strategy and use a third trick: try and square as many LargeInteger as possible. One idea is to group the terms having same powers, multiply them together, then raise to the prescribed power. But if term p is raised to the power of 7, we will have to evaluate (p squared squared) * p squared * p. So we will store p into three collections,&lt;/div&gt;&lt;ul style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;li&gt;the collection of terms raisedTo: 1;&lt;/li&gt;&lt;li&gt;the collection of terms raisedTo: 2;&lt;/li&gt;&lt;li&gt;the collection of terms raisedTo: 4.&lt;/li&gt;&lt;/ul&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;The last point, is that we won't bother with powers of 2, because the fastest variants also don't. Here we come with this algorithm:&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;Integer&amp;gt;&amp;gt;optimizedPrimeFactorFactorial&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; "This is the optimized version of primeFactorFactorial"&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; | powers primes |&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; self &amp;lt;= 1 ifTrue: [^1].&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; primes := (Integer primesUpTo: self + 1) allButFirst.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; powers := primes collect: [:e | self - (self sumDigitsInBase: e) // (e - 1)].&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ^(primes karatsubaProductPowers: powers) bitShift: self - self bitCount&lt;/div&gt;&lt;div style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;SequenceableCollection&amp;gt;&amp;gt;karatsubaProductPowers: powers&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; "Compute the product of self elements, each raised to the corresponding powers"&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; | lastPower rank terms |&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; (lastPower := powers size) = 0 ifTrue: [^1].&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; rank := 1.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; terms := OrderedCollection new: (powers at: 1) highBit.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; [rank &amp;lt;= (powers at: 1)]&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; whileTrue:&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; [ [ rank &amp;gt; (powers at: lastPower) ] whileTrue: [lastPower := lastPower - 1].&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; terms add: ((((1 to: lastPower) select: [:e | ((powers at: e) bitAnd: rank) ~= 0]) collect: [:i | self at: i]) karatsubaProduct raisedToInteger: rank).&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; rank := rank bitShift: 1].&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ^terms karatsubaProduct&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;Smalltalk garbageCollect.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;Time millisecondsToRun: [1 to: 3000 do: [:x | x optimizedPrimeFactorFactorial]].&lt;/span&gt;&lt;br /&gt;&lt;b style="color: blue;"&gt;-&amp;gt;&amp;nbsp; 8436 8433&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;The optimized prime factor algorithm is about 2.25 times faster than the  naive prime factors on small integers up to 3000. &lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;Let's instrument the algorithm to check if the terms are well balanced. We add the line&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; (&lt;/span&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;terms collect: [:e | e highBit]&lt;/span&gt;) inspect.&lt;br /&gt;and check &lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;50000 optimizedPrimeFactorFactorial&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&amp;nbsp;&lt;b style="color: blue;"&gt;-&amp;gt; an OrderedCollection(49775 49532 49490 49130 49165 48285 49407 48651 41929 40562 36299 26336 38838 55004 25969) &lt;/b&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;b&gt;It's remarkable, that we decomposed the factorial of 50000 into terms having about 50000 bits!&lt;/b&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;The score on a larger integer :&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;[50000 factorial] timeToRun.&lt;/span&gt; &lt;b&gt;&lt;span style="color: blue;"&gt;-&amp;gt; 10288&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;[50000 primeFactorFactorial] timeToRun.&lt;b&gt;&lt;span style="color: blue; font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt; -&amp;gt; 8853&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;[50000 optimizedPrimeFactorFactorial] timeToRun.&lt;/span&gt;&lt;b&gt;&lt;span style="color: blue;"&gt; -&amp;gt; 1263&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;[50000 primeSwingFactorial] timeToRun.&lt;/span&gt;&lt;b style="color: blue;"&gt; -&amp;gt; 1004&lt;/b&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;Now a challenge: write &lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;optimizedPrimeFactorFactorial&lt;/span&gt; with Xtreams instead of SequenceableCollection!&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8012131534487039227-2618612731949529748?l=smallissimo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://smallissimo.blogspot.com/feeds/2618612731949529748/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://smallissimo.blogspot.com/2011/07/optimizing-product-of-prime-powers.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8012131534487039227/posts/default/2618612731949529748'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8012131534487039227/posts/default/2618612731949529748'/><link rel='alternate' type='text/html' href='http://smallissimo.blogspot.com/2011/07/optimizing-product-of-prime-powers.html' title='Optimizing the product of prime powers'/><author><name>nicolas cellier</name><uri>http://www.blogger.com/profile/13769333498003444630</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8012131534487039227.post-7489524086846663384</id><published>2011-07-05T22:11:00.000+02:00</published><updated>2011-07-05T22:11:41.583+02:00</updated><title type='text'>Xtreams and Generators</title><content type='html'>In my last post I reported the lack of Generator in Xtreams framework.&lt;br /&gt;Well, I just received this &lt;a href="http://mlucassmith.tumblr.com/post/7273146471/generators-for-xtreams"&gt;clarification&amp;nbsp; &lt;/a&gt;from Michael and Martin, the authors of Xtreams.&lt;br /&gt;Definitely, &lt;a href="http://code.google.com/p/xtreams/"&gt;Xtreams &lt;/a&gt;has a lot of potential!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8012131534487039227-7489524086846663384?l=smallissimo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://smallissimo.blogspot.com/feeds/7489524086846663384/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://smallissimo.blogspot.com/2011/07/xtreams-and-generators.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8012131534487039227/posts/default/7489524086846663384'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8012131534487039227/posts/default/7489524086846663384'/><link rel='alternate' type='text/html' href='http://smallissimo.blogspot.com/2011/07/xtreams-and-generators.html' title='Xtreams and Generators'/><author><name>nicolas cellier</name><uri>http://www.blogger.com/profile/13769333498003444630</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8012131534487039227.post-7813205303577942883</id><published>2011-07-04T23:59:00.000+02:00</published><updated>2011-07-04T23:59:07.394+02:00</updated><title type='text'>Using generators on the primeFactorsFactorial example</title><content type='html'>&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;Last example algorithm, primeFactorsFactorial did involve enumerating of several collections:&lt;/div&gt;&lt;ul&gt;&lt;li&gt;The collection of primes up to n&lt;/li&gt;&lt;li&gt;The collection of powers of these primes&lt;/li&gt;&lt;/ul&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;An alternative is to work with a stream that generates each item on the fly, rather than collecting the whole sequence of values, and then pipe to other kind of streams that transform the values. This technique has two advantages:&lt;/div&gt;&lt;ol style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;li&gt;avoiding allocation of large auxiliary collections that will later be thrown out, can help some algorithms to scale up.&lt;/li&gt;&lt;li&gt;piping could theoretically enable parallel execution if  we had a multi-threaded VM (though in fact we keep some collections, the optimal performance being often reached by tuning some  buffers size, since the cost of inter thread synchronisation is not null)&lt;/li&gt;&lt;/ol&gt;&lt;span style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt; This does not really apply to our prime factors decomposition since the collection of primes are not huge, but we have this example available, let's use it and see how it would be possible in Squeak.&lt;/span&gt;&lt;br /&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;First, Squeak provides an &lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;primesUpTo:do:&lt;/span&gt; taking a block as argument. That's all we need.&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;We can transform this block into a stream using a &lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;Generator&lt;/span&gt;. Let see in class comment how to use it:&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; | generator |&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; generator := Generator on: [:g| Integer primesUpTo: 100 do:[:prime| g yield: prime]].&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; [generator atEnd] whileFalse:[Transcript show: generator next].&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;OK, so a new &lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;Generator&lt;/span&gt; is associated to an outer block, &lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;[:g| Integer primesUpTo: 100 do:[:prime| g yield: prime]]&lt;/span&gt;, which tells which method to execute to produce the sequence of values.&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;The inner block &lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;[:prime| g yield: prime]&lt;/span&gt; just tells the generator that a new prime is available.&amp;nbsp; &lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;Each time we ask for &lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;generator next&lt;/span&gt;, the generator machinery arranges to advance the execution of outer block until it reaches execution of the inner block, &lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&lt;/span&gt;and then switch back and return the prime provided to this block.&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;This is known as the &lt;a href="http://en.wikipedia.org/wiki/Coroutine"&gt;coroutine&lt;/a&gt; technique, and implemented by using a clever a simple hack manipulating the call stack. Look at the implementation by yourself.&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;Note that a Generator now understand &lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;value:&lt;/span&gt; and can be used directly in place of the inner block, try &lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;(Generator on: [:g| Integer primesUpTo: 100 do: g]) contents.&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;Can we apply this to our &lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;primeFactorFactorial&lt;/span&gt;&lt;span style="color: black; font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;?&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;primeFactorFactorialViaGenerator&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;| generator |&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;generator := Generator on: [:g | Integer primesUpTo: self + 1 do: g].&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;^ (generator collect: [:p | p raisedToInteger: self - (self sumDigitsInBase: p) // (p - 1)]) product&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;Hmm, it will not work, because a &lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;Generator&lt;/span&gt; understands only one iteration operator, &lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;do:&lt;/span&gt;, but not &lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;collect:&lt;/span&gt; Squeak streams are a pity.&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;More over, the &lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;collect:&lt;/span&gt; operation if implemented by means of &lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;do:&lt;/span&gt; would not be lazy but rather produce the whole collection of powers. We would have only eliminated the first collection of primes, but not the collection of powers of primes.&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;One good and recent framework - &lt;a href="http://code.google.com/p/xtreams/"&gt;Xtream&lt;/a&gt; - It is an interesting alternative and provides the lazy operations we're looking for; follow the &lt;a href="http://www.squeaksource.com/Xtreams.html"&gt;squeaksource&lt;/a&gt; link to get download instructions. Let's see how we can lazily pipe the operations through streams:&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;primeFactorFactorialViaGeneratorAndXtream&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; | generator stream factorial |&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; generator := Generator&lt;/span&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt; on: [:g | Integer primesUpTo: self + 1 do: g].&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; stream := ((XTBlockClosureReadStream&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; on: [generator atEnd&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ifTrue: [Incomplete raise]&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ifFalse: [generator next]])&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; collecting: [:p | p raisedToInteger: self - (self sumDigitsInBase: p) // (p - 1)])&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; injecting: 1 into: [:product :power | product * power].&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ^ [[factorial := stream get] repeat]&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; on: Incomplete&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; do: [factorial]&lt;/span&gt;&lt;br /&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;Unfortunately Xtream has no &lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;Generator&lt;/span&gt;, so we have to wrap it up in a &lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;BlockClosureReadStream&lt;/span&gt;.&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;Another problem is that &lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;injecting:into:&lt;/span&gt; is not reducing the stream to a single element, instead it answers a stream of all the intermediate results. Since we only need the last one, we have to repeat the operation by ourself, capture and answer the last element when the stream starves (we catch this &lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;Incomplete&lt;/span&gt; exception).&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;a href="http://bugs.squeak.org/bug_view_advanced_page.php?bug_id=6755"&gt;Once&lt;/a&gt; I proposed an alternative selector &lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;^[stream get] repeatUntil: Incomplete&lt;/span&gt;, with a slight modification, this would have been useful; or maybe we could just extend &lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;XTReadStream&lt;/span&gt; to respond to &lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;last&lt;/span&gt;. &lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;Let see how the generator variant performs:&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;Smalltalk garbageCollect.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;Time millisecondsToRun: [1 to: 3000 do: [:x | x primeFactorFactorialViaGeneratorAndXtream] ]&lt;/span&gt;&lt;br /&gt;&lt;b style="color: blue;"&gt;-&amp;gt; 22835 22529&lt;/b&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;This is to be compared to the &lt;b style="color: blue;"&gt;19136ms&amp;nbsp;&lt;/b&gt;of naive form. Well, that was expected, we eliminated the intermediate collections, but they did not cost that much in this case. Instead we pay a price for indirection and maybe also the Generator trick forces COG VM to un-optimize some portions. But that doesn't matter, we saw some smart streaming techniques.&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;A more difficult exercise would be to transform a divide and conquer recursive product evaluation variant into a streaming equivalence... Yet I do not know how, but if I find it, this will be another post.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8012131534487039227-7813205303577942883?l=smallissimo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://smallissimo.blogspot.com/feeds/7813205303577942883/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://smallissimo.blogspot.com/2011/07/using-generators-on-primefactorsfactori.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8012131534487039227/posts/default/7813205303577942883'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8012131534487039227/posts/default/7813205303577942883'/><link rel='alternate' type='text/html' href='http://smallissimo.blogspot.com/2011/07/using-generators-on-primefactorsfactori.html' title='Using generators on the primeFactorsFactorial example'/><author><name>nicolas cellier</name><uri>http://www.blogger.com/profile/13769333498003444630</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8012131534487039227.post-7581906215231859484</id><published>2011-07-03T06:00:00.032+02:00</published><updated>2011-07-03T13:43:37.569+02:00</updated><title type='text'>Evaluating a factorial from its prime factors</title><content type='html'>&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;Again, I will evaluate a suboptimal algorithm because it is nice and fun in Smalltalk.&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;I guess in other languages too, especially functional languages, but you know my favourite path.&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;The exploration started with this little &lt;a href="http://www.parcplace.net/list/vwnc-archive/1106/msg00080.html"&gt;factorial contest&lt;/a&gt; submitted by Paul Baumann.&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;We already know the fastest algorithm are the &lt;a href="http://www.luschny.de/math/factorial/index.html"&gt;prime swing variant&lt;/a&gt; (read this &lt;a href="https://oeis.org/wiki/User:Peter_Luschny/TheLostCatalanNumbers"&gt;wiki&lt;/a&gt; to get an explanation of swing by Peter Luschny), and simple and clever &lt;a href="http://www.parcplace.net/list/vwnc-archive/1106/msg00089.html"&gt;split recursive algorithm submitted&lt;/a&gt; by John Brant.&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;In both cases, only the odd products are performed, in a divide and conquer fashion which produces well balanced large integers (this is important for accelerated products like &lt;a href="http://en.wikipedia.org/wiki/Karatsuba_algorithm"&gt;Karatsuba&lt;/a&gt; &lt;a href="http://en.wikipedia.org/wiki/Toom%E2%80%93Cook_multiplication"&gt;Toom&lt;/a&gt; or &lt;a href="http://en.wikipedia.org/wiki/Sch%C3%B6nhage%E2%80%93Strassen_algorithm"&gt;FFT&lt;/a&gt;). The final power of two being replaced by a &lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;bitShift:&lt;/span&gt; which saves many costly LargeInteger multiplications.&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;Our suboptimal variant of interest consists in evaluating the factorial from its decomposition in prime factors. We know that each prime &lt;span style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;lt;= n&lt;/span&gt; will be compose &lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;n factorial&lt;/span&gt;, but we also know the &lt;a href="http://planetmath.org/encyclopedia/PrimePowerDividingAFactorial.html"&gt;power of each of these primes&lt;/a&gt; thanks to Legendre. This algorithm can be naively transcribed in Smalltalk:&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;Integer&amp;gt;&amp;gt;primeFactorFactorial&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; "Recompose the factorial from the prime factors, knowing the power of each prime."&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ^((Integer primesUpTo: self + 1) collect: [:p |&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; p raisedToInteger: self - (self sumDigitsInBase: p) // (p - 1)]) product&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;primesUpTo:&lt;/span&gt; is a method found in Squeak which use a sieve of Eratosthenes, up to means not inclusive, so we need the disgracious + 1. Then Squeak lacks two methods, &lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;sumDigitsInBase:&lt;/span&gt; and &lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;product&lt;/span&gt;.&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;A naive &lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;product&lt;/span&gt;, could be simply:&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;Collection&amp;gt;&amp;gt;product&lt;/div&gt;&lt;div style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ^self inject: 1 into: [:product :element | product * element]&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;With this definition, &lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;Collection new product&lt;/span&gt; is answering &lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;1&lt;/span&gt;, and we don't need any protection for evaluating &lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;0 primeFactorFactorial&lt;/span&gt;.&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;For sure, it won't be efficient and should better be replaced by a divide and conquer variant, but we'll see this in another post.&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;A naive &lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;sumDigitsInBase:&lt;/span&gt; could be:&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;Integer&amp;gt;&amp;gt;sumDigitsInBase: base&lt;/div&gt;&lt;div style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ^(self printStringBase: base) inject: 0 into: [:sum :digit | sum + digit digitValue]&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;OK, we're done...&lt;/div&gt;&lt;div style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp; &amp;nbsp; 1000 primeFactorFactorial.&lt;b style="color: blue;"&gt;&lt;span style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt; -&amp;gt; Error: subscript is out of bounds: 303&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;Oops! Unfortunately, it's not only suboptimal, it won't work for primes above 36 because Squeak has no idea which character to use to represent digit 37. Anyway, even with unicode we would only have a limited set of characters. Huge, but limited.&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;It does not matter anyway, we can just reimplement &lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;printStringBase:&lt;/span&gt; and instead of streaming out digits converted to characters, just sum the digits.&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;A naive algorithm would be to just remove the last digit (the remainder by a division by base):&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;Integer&amp;gt;&amp;gt;sumDigitsInBase: base&lt;br /&gt;&amp;nbsp; &amp;nbsp; "Answer the sum&amp;nbsp; &lt;/div&gt;&lt;div style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp; &amp;nbsp; | sum |&lt;/div&gt;&lt;div style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; sum := 0.&lt;/div&gt;&lt;div style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; q := self abs.&lt;/div&gt;&lt;div style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; [q = 0]&lt;/div&gt;&lt;div style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; whileFalse:&lt;/div&gt;&lt;div style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [sum := sum + (q - ((q := q // base) * base))].&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp; &amp;nbsp; ^sum &lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;Since we probably won't compute the factorial of a LargeInteger, this shall be enough. &lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;For LargeInteger, we would use a divide and conquer method in order to avoid repeated LargeInteger divisions, and replace them by as many SmallInteger divisions as possible. This would be the exact image of &lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;printStringBase:&lt;/span&gt;, so we won't develop it here.&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;Now we are done with this very naive implementation. Let's see how it performs on COG VM:&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;Smalltalk garbageCollect.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;Time millisecondsToRun: [1 to: 3000 do: [:x | x factorial]].&lt;/span&gt;&lt;br /&gt;&lt;b&gt;&lt;span style="color: blue;"&gt;-&amp;gt; &lt;/span&gt;&lt;span style="color: blue;"&gt;29753 29780&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;Smalltalk garbageCollect.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;Time millisecondsToRun: [1 to: 3000 do: [:x | x primeFactorFactorial]].&lt;/span&gt;&lt;br /&gt;&lt;b style="color: blue;"&gt;-&amp;gt; 19204 19136&lt;/b&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;Incredible, with this very naive code we already gain 33%. In fact, any implementation will probably beat factorial performance, but not its simplicity.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8012131534487039227-7581906215231859484?l=smallissimo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://smallissimo.blogspot.com/feeds/7581906215231859484/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://smallissimo.blogspot.com/2011/07/evaluating-factorial-from-its-prime.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8012131534487039227/posts/default/7581906215231859484'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8012131534487039227/posts/default/7581906215231859484'/><link rel='alternate' type='text/html' href='http://smallissimo.blogspot.com/2011/07/evaluating-factorial-from-its-prime.html' title='Evaluating a factorial from its prime factors'/><author><name>nicolas cellier</name><uri>http://www.blogger.com/profile/13769333498003444630</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8012131534487039227.post-1272525587779503494</id><published>2011-07-02T00:58:00.002+02:00</published><updated>2011-07-02T04:45:48.414+02:00</updated><title type='text'>Revisiting the sieve of Eratosthenes</title><content type='html'>&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;Welcome, this is my first blogger blogging about Smalltalk, and its Squeak flavour.&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;Today, I will revisit the sieve of Eratosthenes for fun.&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;I don't think I need to introduce this &lt;a href="http://en.wikipedia.org/wiki/Sieve_of_Eratosthenes"&gt;famous algorithm&lt;/a&gt;. &lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;The first idea is to use integers as arrays of bits, because it is fun.&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;If p is a composite integer, then the bit of rank p will be set to 1.&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;The second idea is to use an integer division to produce the repeated bit pattern using this property:&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; (2r11111111111 // 2r11) printStringBase: 2.&lt;/span&gt; &lt;b style="color: blue;"&gt;-&amp;gt; '1010101010'&lt;/b&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; (2r11111111111111 // 2r111) printStringBase: 2.&lt;/span&gt; &lt;b style="color: blue;"&gt;-&amp;gt; '100100100100'&lt;/b&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; (2r1111111111111111111 // 2r1111) printStringBase: 2.&lt;/span&gt; &lt;b style="color: blue;"&gt;-&amp;gt; '1000100010001000'&lt;/b&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;OK, I think you get the idea of division. Now we need two things:&lt;/div&gt;&lt;ol style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;li&gt;get the right number of &lt;span style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;1&lt;/span&gt; left of &lt;span style="color: #4c1130;"&gt;//&lt;/span&gt;&lt;/li&gt;&lt;li&gt;remove the trailing &lt;span style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;1&lt;/span&gt; in the quotient&lt;/li&gt;&lt;/ol&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;We can do both with &lt;span style="color: #4c1130;"&gt;bitShift:&lt;/span&gt; or using the binary selector &lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;If &lt;span style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;p&lt;/span&gt; is prime, and we want all primes up to &lt;span style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;n&lt;/span&gt;, then the adequate bit pattern is produced by:&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1 &amp;lt;&amp;lt; (n // p - 1 * p) - 1 // (1 &amp;lt;&amp;lt; p - 1) &amp;lt;&amp;lt; (p &amp;lt;&amp;lt; 1 - 1).&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;Mind the parenthesis, above expression is a bit tricky...&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;Remember, Smalltalk binary operators read from left to right, all with same precedence.&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;First operation produces the &lt;span style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;1&lt;/span&gt;s left of &lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;//&lt;/span&gt;:&lt;/div&gt;&lt;div style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp; 1 &amp;lt;&amp;lt; (n // p - 1 * p) - 1&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;Indeed, we need a length which is multiple of &lt;span style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;p&lt;/span&gt; in order to get a trailing &lt;span style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;1&lt;/span&gt; in the quotient&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;And we need enough bits to obtain a quotient with a leading &lt;span style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;1&lt;/span&gt; of rank &amp;lt;= &lt;span style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;n - (2*p-1)&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;Second operation is the division by appropriate number of &lt;span style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;1&lt;/span&gt;s (&lt;span style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;p&lt;/span&gt;):&lt;/div&gt;&lt;div style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&lt;span style="color: #4c1130;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;  // (1 &amp;lt;&amp;lt; p - 1)&lt;/span&gt; &lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;Third operation shift by &lt;span style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;2*p - 1&lt;/span&gt; to obtain the trailing &lt;span style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;0&lt;/span&gt;s:&lt;/div&gt;&lt;div style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&amp;lt; (p &amp;lt;&amp;lt; 1 - 1)&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;Indeed, we need &lt;span style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;p - 1&lt;/span&gt; to align the &lt;span style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;1&lt;/span&gt;s on rank multiples of &lt;span style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;p&lt;/span&gt;, + &lt;span style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;p&lt;/span&gt; to clear the trailing &lt;span style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;1&lt;/span&gt;.&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;Of course, I can propose a few variants, for example a single &lt;span style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;1&lt;/span&gt; is enough left of &lt;span style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;//&lt;/span&gt;:&lt;/div&gt;&lt;div style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1 &amp;lt;&amp;lt; (n // p - 1 * p) // (1 &amp;lt;&amp;lt; p - 1) &amp;lt;&amp;lt; (p &amp;lt;&amp;lt; 1 - 1).&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;We can just complete the missing trailing &lt;span style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;0&lt;/span&gt;s:&amp;nbsp; &lt;/div&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1 &amp;lt;&amp;lt; (n - p)&amp;nbsp; // (1 &amp;lt;&amp;lt; p - 1) &amp;lt;&amp;lt; (p &amp;lt;&amp;lt; 1 - 1 - (n \\ p)).&lt;/span&gt; &lt;br /&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;Or arrange to have first &lt;span style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;p - 1&lt;/span&gt; trailing &lt;span style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;0&lt;/span&gt;s produced by the division:&lt;/div&gt;&lt;div style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp; &amp;nbsp; 1 &amp;lt;&amp;lt; (n // p * p - 1) // (1 &amp;lt;&amp;lt; p - 1) &amp;lt;&amp;lt; p.&lt;/div&gt;&lt;br /&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;The last one looks good, we are ready to produce the composite mask up to n:&lt;/div&gt;&lt;br /&gt;&lt;div style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; p := 1.&lt;/div&gt;&lt;div style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; composite := 1.&lt;/div&gt;&lt;div style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; [ p &amp;lt;= n ]&lt;/div&gt;&lt;div style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; whileTrue: &lt;/div&gt;&lt;div style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; [(composite bitAt: p) = 0&lt;/div&gt;&lt;div style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ifTrue:&lt;/div&gt;&lt;div style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ["p is prime, mark all multiple of p up to n as composite"&lt;/div&gt;&lt;div style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; composite := composite bitOr: 1 &amp;lt;&amp;lt; (n // p * p - 1) // (1 &amp;lt;&amp;lt; p - 1) &amp;lt;&amp;lt; p ].&lt;/div&gt;&lt;div style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; p := p + 1].&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;Of course we could stop the loop at &lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;n sqrtFloor&lt;/span&gt;, increment by &lt;span style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;2&lt;/span&gt; from second loop etc...&lt;/div&gt;&lt;span style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;We could also enumerate primes by feeding a block with p inside the &lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;ifTrue: [ ]&lt;/span&gt;.&lt;/span&gt;&lt;br /&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;But let's have fun by enumerating primes from the composite mask with bit tricks.&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;For example, we want to collect primes in an Array. &lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;To know the number of primes up to &lt;span style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;n&lt;/span&gt;, we just need to count the number of bits set to &lt;span style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;0&lt;/span&gt;.&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;Or subtract &lt;span style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;n&lt;/span&gt; with number of bit set to &lt;span style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;1&lt;/span&gt;.&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; numberOfPrimes := n - composite bitCount.&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;Then, we just enumerate by finding and removing next bit set to zero, starting at least significant bit.&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; (Array new: numberOfPrimes) collect: [:void |&lt;/div&gt;&lt;div style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; | isolatedBit |&lt;/div&gt;&lt;div style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; "find next zero in composite"&lt;/div&gt;&lt;div style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; isolatedBit := composite bitXor: composite + 1.&lt;/div&gt;&lt;div style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; "remove next zero in composite"&lt;/div&gt;&lt;div style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; composite := composite bitOr: isolatedBit.&lt;/div&gt;&lt;div style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; isolatedBit highBit]&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;Indeed, &lt;span style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;2rxxxxx01111 + 1&lt;/span&gt; will generate a carry up to trailing &lt;span style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;0&lt;/span&gt;, and result in &lt;span style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;2rxxxxx10000&lt;/span&gt;, the leading &lt;span style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;xxxxx&lt;/span&gt; being unchanged.&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;The &lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;bitXor:&lt;/span&gt; then will remove the leading &lt;span style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;xxxxx&lt;/span&gt;, and result in &lt;span style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;2r11111&lt;/span&gt;.&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;We then just need to get the rank of the highest bit, which is &lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;highBit&lt;/span&gt;'s job...&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;An alternative is to first reverse the bits of composite mask.&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;Here we will just print the primes in the &lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;Transcript&lt;/span&gt;:&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; composite := 1 &amp;lt;&amp;lt; n - 1 - composite.&lt;/div&gt;&lt;div style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; [composite &amp;gt; 0] whileTrue:&lt;/div&gt;&lt;div style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [Transcript cr; show: composite lowBit.&lt;/div&gt;&lt;div style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; composite := composite bitAnd: composite - 1]&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;Same here, &lt;span style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;2rxxxxx10000 - 1&lt;/span&gt; will generate a carry up to trailing &lt;span style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;1&lt;/span&gt; and result in &lt;span style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;2rxxxxx01111&lt;/span&gt;, the leading &lt;span style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;xxxxx&lt;/span&gt; being unchanged. Then &lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;bitAnd:&lt;/span&gt; will just clear all but the leading &lt;span style="font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;xxxxx&lt;/span&gt;.&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;Of course, this method is not really efficient because each &lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;bitOr:&lt;/span&gt; and &lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;bitXor:&lt;/span&gt; operation will allocate a new &lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;LargePositiveInteger&lt;/span&gt;, not counting all the &lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;bitShift:&lt;/span&gt;, additions and subtractions, but do we care? Squeak &lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;Integer class&amp;gt;&amp;gt;primesUpTo:&lt;/span&gt; is already fast, we don't need another one... &lt;/div&gt;&lt;br /&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;Nastily, I removed the comments, obfuscated the names, and factored out repeated code with additional temps. It's not a good idea because some operations leaked out the primality condition block, but just for the pleasure to quizz colleagues:&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;quizz: aBlock&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; "Could you tell which serie will feed aBlock  when this message is sent to an integer n?&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; What the return value means?"&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; | s t x y z |&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; s := (x := y := 1) &amp;lt;&amp;lt; self - 2.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; [(x := x + 1) &amp;lt;= self]&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; whileTrue:&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; [y := (z := y) &amp;lt;&amp;lt; 1 + 1.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; (s bitAnd: (t := z + 1)) = 0&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ifFalse:&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; [aBlock value: x.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; s := s bitAnd: z &amp;lt;&amp;lt; (self // x * x + x) // y + t]].&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ^s&lt;/span&gt;&lt;/div&gt;&lt;div style="color: black; font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;span style="color: #4c1130; font-family: &amp;quot;Helvetica Neue&amp;quot;,Arial,Helvetica,sans-serif;"&gt;&lt;span style="color: black; font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;Did you notice the variant?&lt;/span&gt;&lt;/span&gt; &lt;/div&gt;&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif;"&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8012131534487039227-1272525587779503494?l=smallissimo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://smallissimo.blogspot.com/feeds/1272525587779503494/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://smallissimo.blogspot.com/2011/07/revisiting-sieve-of-erathostenes.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8012131534487039227/posts/default/1272525587779503494'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8012131534487039227/posts/default/1272525587779503494'/><link rel='alternate' type='text/html' href='http://smallissimo.blogspot.com/2011/07/revisiting-sieve-of-erathostenes.html' title='Revisiting the sieve of Eratosthenes'/><author><name>nicolas cellier</name><uri>http://www.blogger.com/profile/13769333498003444630</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
