<div dir="ltr">Hi Nicolas,<br><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Mar 6, 2015 at 10:35 AM, Nicolas Cellier <span dir="ltr">&lt;<a href="mailto:ncellier@ifrance.com" target="_blank">ncellier@ifrance.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"> <br><div dir="ltr"><div><div><div><div><div><div><div><div><div><div><div><div>I&#39;m trying to understand the negative case...<br><br></div>We have the magnitude on one side xMag<br></div>We minSmallInteger in two complement on the other side yTC<br></div>We know that the magnitude of minSmallInteger is yMag=bitInvert(yTC)+1<br></div>We know that all bytes of yTC are 0 but the MSB<br></div>Thus all bytes of bitInvert(yTC) are 16rFF<br></div>Thus all bytes of yMag are 0, but the highest which is (MSB(yTC) xOr: 256) + 1.<br><br></div>Thus, assuming same byte length:<br>MSB(xMag) &lt; MSB(yMag) =&gt; x is a CSI<br>MSB(xMag) &gt; MSB(yMag) =&gt; x is large<br>MSB(xMag) = MSB(yMag) =&gt; we must inquire the LSBs of xMag..<br></div>(1 to: len-1) anySatisfy: [:i | (xMag digitAt: i) ~= 0] =&gt; x isLarge<br></div>otherwise, x is minSmallInteger<br><br></div>Eliot, I fail to see the bitInvert(MSB(minSmallInteger))+1 in your code...<br></div>Did I miss something?<br></div></div></blockquote><div><br></div><div>You&#39;re talking about normalizeNegative: right?  I haven&#39;t changed anything fundamental here.  The check is in</div><div><br></div><div><div><span class="" style="white-space:pre">        </span>len &lt;= sLen ifTrue: </div><div><span class="" style="white-space:pre">                </span>[(len &lt; sLen</div><div><span class="" style="white-space:pre">                </span>  or: [(pointer at: sLen - 1)</div><div><span class="" style="white-space:pre">                                </span>&lt; (self cDigitOfCSI: interpreterProxy minSmallInteger at: sLen)]) ifTrue: &quot;interpreterProxy minSmallInteger lastDigit&quot;</div><div><span class="" style="white-space:pre">                        </span>[&quot;If high digit less, then can be small&quot;</div><div><span class="" style="white-space:pre">                        </span>val := 0 - (pointer at: (len := len - 1)).</div><div><span class="" style="white-space:pre">                        </span>len - 1 to: 0 by: -1 do:</div><div><span class="" style="white-space:pre">                                </span>[:i | val := val * 256 - (pointer at: i)].</div><div><span class="" style="white-space:pre">                        </span>^val asOop: SmallInteger].</div><div><span class="" style="white-space:pre">                </span> 1 to: sLen do:</div><div><span class="" style="white-space:pre">                        </span>[:i | | byte | &quot;If all digits same, then = minSmallInteger (sr: minSmallInteger digits 1 to sLen - 1 are 0)&quot;</div><div><span class="" style="white-space:pre">                        </span>byte := i &gt; len ifTrue: [0] ifFalse: [pointer at: i - 1].</div><div><span class="" style="white-space:pre">                        </span>byte ~= (self cDigitOfCSI: interpreterProxy minSmallInteger at: i) ifTrue: &quot;Not so; return self shortened&quot;</div><div><span class="" style="white-space:pre">                                </span>[len &lt; oldLen ifTrue: &quot;^ self growto: len&quot;</div><div><span class="" style="white-space:pre">                                        </span>[^self bytes: aLargeNegativeInteger growTo: len].</div><div><span class="" style="white-space:pre">                                </span> ^aLargeNegativeInteger]].</div><div><span class="" style="white-space:pre">                </span> ^interpreterProxy minSmallInteger asOop: SmallInteger].</div></div><div><br></div><div>The first part deals with the simple case of something shorter than SmallInteger minVal, or the same length whose top byte is less:</div><div><br></div><div><div><span class="" style="white-space:pre">                </span>(len &lt; sLen</div><div><span class="" style="white-space:pre">                </span>  or: [(pointer at: sLen - 1)</div><div><span class="" style="white-space:pre">                                </span>&lt; (self cDigitOfCSI: interpreterProxy minSmallInteger at: sLen)]) ifTrue: &quot;interpreterProxy minSmallInteger lastDigit&quot;</div><div><span class="" style="white-space:pre">                        </span>[&quot;If high digit less, then can be small&quot;</div><div><span class="" style="white-space:pre">                        </span>val := 0 - (pointer at: (len := len - 1)).</div><div><span class="" style="white-space:pre">                        </span>len - 1 to: 0 by: -1 do:</div><div><span class="" style="white-space:pre">                                </span>[:i | val := val * 256 - (pointer at: i)].</div><div><span class="" style="white-space:pre">                        </span>^val asOop: SmallInteger].</div></div><div><br></div><div> The second part deals with the possibility of SmallInteger minVal:</div><div><br></div><div><div><div><span class="" style="white-space:pre">                </span> 1 to: sLen do:</div><div><span class="" style="white-space:pre">                        </span>[:i | | byte | &quot;If all digits same, then = minSmallInteger (sr: minSmallInteger digits 1 to sLen - 1 are 0)&quot;</div><div><span class="" style="white-space:pre">                        </span>byte := i &gt; len ifTrue: [0] ifFalse: [pointer at: i - 1].</div><div><span class="" style="white-space:pre">                        </span>byte ~= (self cDigitOfCSI: interpreterProxy minSmallInteger at: i) ifTrue: &quot;Not so; return self shortened&quot;</div><div><span class="" style="white-space:pre">                                </span>[len &lt; oldLen ifTrue: &quot;^ self growto: len&quot;</div><div><span class="" style="white-space:pre">                                        </span>[^self bytes: aLargeNegativeInteger growTo: len].</div><div><span class="" style="white-space:pre">                                </span> ^aLargeNegativeInteger]].</div><div><span class="" style="white-space:pre">                </span> ^interpreterProxy minSmallInteger asOop: SmallInteger].</div></div></div><div><br></div><div>The bit invert is in cDigitOfCSI:at: </div><div><span style="white-space:pre">        </span>cDigitOfCSI: csi at: ix <br></div><div><div><span style="white-space:pre">                ^</span>(csi &lt; 0</div><div><span class="" style="white-space:pre">                        </span>ifTrue: [0 - csi]</div><div><span class="" style="white-space:pre">                        </span>ifFalse: [csi]) &gt;&gt; (ix - 1 * 8) bitAnd: 255</div></div><div><br></div><div>answers 64 for &quot;self cDigitOfCSI: interpreterProxy minSmallInteger at: 4&quot; in 32 bits (16 in 64-bits).  So cDigitOfCSI:at: is answering magnitude, not 2&#39;s complement bytes.</div><div><br></div><div>Here&#39;s the original code before I streamlined it.  I don&#39;t see a significant difference:</div><div><br></div><div><div><span class="" style="white-space:pre">        </span>len &lt;= sLen</div><div><span class="" style="white-space:pre">                </span>ifTrue: </div><div><span class="" style="white-space:pre">                        </span>[&quot;SmallInteger minVal&quot;</div><div><span class="" style="white-space:pre">                        </span>minVal := interpreterProxy minSmallInteger.</div><div><span class="" style="white-space:pre">                        </span>(len &lt; sLen or: [(self digitOfBytes: aLargeNegativeInteger at: sLen)</div><div><span class="" style="white-space:pre">                                        </span>&lt; (self cDigitOfCSI: minVal at: sLen)</div><div><span class="" style="white-space:pre">                                </span>&quot;minVal lastDigit&quot;])</div><div><span class="" style="white-space:pre">                                </span>ifTrue: </div><div><span class="" style="white-space:pre">                                        </span>[&quot;If high digit less, then can be small&quot;</div><div><span class="" style="white-space:pre">                                        </span>val := 0.</div><div><span class="" style="white-space:pre">                                        </span>len</div><div><span class="" style="white-space:pre">                                                </span>to: 1</div><div><span class="" style="white-space:pre">                                                </span>by: -1</div><div><span class="" style="white-space:pre">                                                </span>do: [:i | val := val * 256 - (self unsafeByteOf: aLargeNegativeInteger at: i)].</div><div><span class="" style="white-space:pre">                                        </span>^ val asOop: SmallInteger].</div><div><span class="" style="white-space:pre">                        </span>1 to: sLen do: [:i | &quot;If all digits same, then = minVal (sr: minVal digits 1 to 3 are 0)&quot;</div><div><span class="" style="white-space:pre">                                </span>(self digitOfBytes: aLargeNegativeInteger at: i)</div><div><span class="" style="white-space:pre">                                        </span>= (self cDigitOfCSI: minVal at: i)</div><div><span class="" style="white-space:pre">                                        </span>ifFalse: [&quot;Not so; return self shortened&quot;</div><div><span class="" style="white-space:pre">                                                </span>len &lt; oldLen</div><div><span class="" style="white-space:pre">                                                        </span>ifTrue: [&quot;^ self growto: len&quot;</div><div><span class="" style="white-space:pre">                                                                </span>^ self bytes: aLargeNegativeInteger growTo: len]</div><div><span class="" style="white-space:pre">                                                        </span>ifFalse: [^ aLargeNegativeInteger]]].</div><div><span class="" style="white-space:pre">                        </span>^ minVal asOop: SmallInteger].</div></div><div><br></div><div>Or am I misunderstanding?</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="ltr"><div><br></div>Nicolas<br></div><div class="gmail_extra"><br><div class="gmail_quote">2015-03-06 0:37 GMT+01:00 Eliot Miranda <span dir="ltr">&lt;<a href="mailto:eliot.miranda@gmail.com" target="_blank">eliot.miranda@gmail.com</a>&gt;</span>:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"> <br><div dir="ltr">Hi Nicolas,<div><br></div><div>   I found my misunderstanding.  Can you review this version instead?</div><div><br></div><div><br></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Mar 5, 2015 at 11:41 AM, Eliot Miranda <span dir="ltr">&lt;<a href="mailto:eliot.miranda@gmail.com" target="_blank">eliot.miranda@gmail.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="ltr">Hi Nicolas,<div><br></div><div>     would you mind also reviewing the attached changes?  There&#39;s a bug in them somewhere, although I think they&#39;re close to correct.  The ideas here are to</div><div><br></div><div>- avoid calling firstIndexableField: on every call to unsafeByteOf:at: in isNormalized:, normalizePositive: and normalizeNegative:.  Do this by cacheing firstIndexableField in a local pointer variable</div><div>- move the bounds check in cDigitOfCSI:at: out to clients that aren&#39;t invoking cDigitOfCSI:at: with in-bounds indices</div><div>- avoid the immediate test in digitLengthOf: when it is known that the object is non-immediate.  Do so by adding digitLengthOfNonImmediate:.</div><div><br></div><div>Of course this approach can be extended to other LargeIntegers methods, but one step at a time :-/</div></div><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Mar 4, 2015 at 2:49 PM, Nicolas Cellier <span dir="ltr">&lt;<a href="mailto:nicolas.cellier.aka.nice@gmail.com" target="_blank">nicolas.cellier.aka.nice@gmail.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"> <br><div dir="ltr"><div><div><br>sLen := interpreterProxy minSmallInteger &gt; 16r3FFFFFFF<br><br></div>sounds like a copy/paste error<br></div>I would expect maxSmallInteger here.<br></div>
<br></blockquote></div><span><font color="#888888"><br><br clear="all"><div><br></div>-- <br><div>best,<div>Eliot</div></div>
</font></span></div>
</blockquote></div><br><br clear="all"><div><br></div>-- <br><div>best,<div>Eliot</div></div>
</div>
<br></blockquote></div><br></div>
<br></blockquote></div><br><br clear="all"><div><br></div>-- <br><div class="gmail_signature">best,<div>Eliot</div></div>
</div></div>