<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">2017-10-12 17:46 GMT+02:00 Bert Freudenberg <span dir="ltr"><<a href="mailto:bert@freudenbergs.de" target="_blank">bert@freudenbergs.de</a>></span>:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div style="font-family:arial,helvetica,sans-serif;font-size:small;color:rgb(0,0,0)"><span style="font-family:arial,sans-serif;color:rgb(34,34,34)">On Thu, Oct 12, 2017 at 11:36 AM, Alan Pinch </span><span dir="ltr" style="font-family:arial,sans-serif;color:rgb(34,34,34)"><<a href="mailto:alan.c.pinch@gmail.com" target="_blank">alan.c.pinch@gmail.com</a>></span><span style="font-family:arial,sans-serif;color:rgb(34,34,34)"> wrote:</span><br></div><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
  
    
  
  <div bgcolor="#FFFFFF">
    <p>The same issue exists in ASN1 support, none for float type tag 9.
      I would love to add this support but I am unsure how to breakdown
      a float into mantissa, base and exponent. Here is a description of
      how ASN1 formats a REAL into the stream of bytes:<br>
    </p>
    <blockquote>Type REAL takes values that are the machine
      representation of a real number, namely the triplet (m, b, e),
      where m is the mantissa (a signed number), b the base (2 or 10),
      and e the exponent (a signed number). For example, the
      representation of the value 3.14 for the variable Pi, declared as
      Pi ::= REAL, can be (314, 10, -2). Three special values,
      PLUS-INFINITY, 0, and MINUS-INFINITY, are also allowed.</blockquote>
    Here are some sample values:<br>
    <blockquote>
      <ul>
        <li>09 00 = 0 (zero)</li>
        <li>09 01 40 = +INF (infinity)</li>
        <li>09 01 41 = -INF</li>
        <li>09 08 03 2b 31 2e 30 65 2b 30 = "+1.0e+0" = 1.0 (exact
          decimal)</li>
        <li>09 05 80 fe 55 55 55 = 1398101.25 (binary, 0x555555 * 2^-2)</li>
        <li>09 06 83 00 fc 00 00 01 = 0.0625 (binary, 0x000001 * 2^-4)<br>
        </li>
      </ul>
    </blockquote>
    I have not parsed out these samples into these components so it's
    greek.</div></blockquote><div><br></div><div><div style="font-family:arial,helvetica,sans-serif;font-size:small;color:rgb(0,0,0)">​Well it's not the same issue as ​<span style="font-family:arial,sans-serif;color:rgb(34,34,34)">ASN.1 float representation is different from IEEE 754 format. To convert a Squeak Float into an IEEE 64 bit pattern we simply access its underlying representation, because the VM uses IEEE internally.</span></div><div style="font-family:arial,helvetica,sans-serif;font-size:small;color:rgb(0,0,0)"><span style="font-family:arial,sans-serif;color:rgb(34,34,34)"><br></span></div><div style="font-family:arial,helvetica,sans-serif;font-size:small;color:rgb(0,0,0)"><span style="font-family:arial,sans-serif;color:rgb(34,34,34)">It sounds like ASN.1 stores mantissa, base, and exponent separately. IEEE calls the mantissa "significand" and that's the name of the corresponding Squeak method. The exponent is called "exponent", and the base is implicitly 2:</span></div><div style="font-family:arial,helvetica,sans-serif;font-size:small;color:rgb(0,0,0)"><span style="font-family:arial,sans-serif;color:rgb(34,34,34)"><br></span></div><div><div style="color:rgb(0,0,0);font-family:arial,helvetica,sans-serif;font-size:small"><div>1398101.25 significand</div><div>=> 1.3333332538604736</div><div>1398101.25 exponent</div><div>=> 20</div><div>1.3333332538604736 timesTwoPower: 20</div><div>=> 1.39810125e6</div><div>1398101.25 = 1.39810125e6</div><div>=> true</div><div><br></div></div><div style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:small">The IEEE significand/mantissa is normalized to a fractional number 1 <= m < 2. ASN wants integral numbers, so you could convert it to an integer like this:</div><div style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:small"><br></div><div><div style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:small"><div>x := 1398101.25.</div><div>mantissa := x significand.</div><div>exponent := x exponent.</div><div>base := 2.</div><div>[mantissa fractionPart isZero] whileFalse:</div><div><span style="white-space:pre-wrap"> </span>[mantissa := mantissa * base.</div><div><span style="white-space:pre-wrap">    </span>exponent := exponent - 1].</div><div>{mantissa asInteger hex. base. exponent}</div><div> #('16r555555' 2 -2)</div><div><br></div></div></div></div><div style="font-family:arial,helvetica,sans-serif;font-size:small;color:rgb(0,0,0)">... which matches your example.</div></div><div style="font-family:arial,helvetica,sans-serif;font-size:small;color:rgb(0,0,0)"><br></div><div style="font-family:arial,helvetica,sans-serif;font-size:small;color:rgb(0,0,0)">I'm sure Nicolas will have a much more efficient formula, but this would work :)</div><span class="gmail-m_5888961250713830924HOEnZb"><font color="#888888"><div style="font-family:arial,helvetica,sans-serif;font-size:small;color:rgb(0,0,0)"><br></div><div style="font-family:arial,helvetica,sans-serif;font-size:small;color:rgb(0,0,0)">- Bert -</div></font></span></div></div></div>
<br><br></blockquote><div>make it right > make it fast so it sounds like a good starting point :)<br></div><div>since I see a lot of logic in the complex ASN1 spec, it'll be even worse when reading!</div><div>I see nothing about negative zero, nan seems handled by later version if we can trust SO answers.<br></div><div>In any case, like requested on SO, a good reference test database sounds mandatory.<br></div></div><div class="gmail_quote"><br></div><div class="gmail_quote">We could also peek what Juan did in Cuis, like:</div><div class="gmail_quote"><br></div><div class="gmail_quote">Float>>exponentPart<br>    "Alternative implementation for exponent"<br>    ^self partValues: [ :sign :exponent :mantissa | exponent ]</div><div class="gmail_quote"><br></div><div class="gmail_quote">partValues: aThreeArgumentBlock<br>    ^ self<br>        partValues: aThreeArgumentBlock<br>        ifInfinite: [ self error: 'Can not handle infinity' ]<br>        ifNaN: [ self error: 'Can not handle Not-a-Number' ].</div><div class="gmail_quote"><br></div><div class="gmail_quote">partValues: aThreeArgumentBlock ifInfinite: aZeroOrOneArgBlock ifNaN: otherZeroOrOneOrTwoArgBlock<br>    "<br>    Float pi hex print<br>    Float pi partValues: [ :sign :exponent :mantissa | { sign hex. exponent hex. mantissa hex} print ]<br>    0.0 partValues: [ :sign :exponent :mantissa | { sign hex. exponent hex. mantissa hex} print ]<br>    For 0.0, exponent will be the minimum possible, i.e.  -1023, and mantissa will be 0.<br>    "<br>    | allBits sign exponent mantissa exponentBits fractionBits |<br><br>    " Extract the bits of an IEEE double float "<br>    allBits _ ((self basicAt: 1) bitShift: 32) + (self basicAt: 2).<br><br>    " Extract the sign and the biased exponent "<br>    sign _ (allBits bitShift: -63) = 0 ifTrue: [1] ifFalse: [-1].<br>    exponentBits _ (allBits bitShift: -52) bitAnd: 16r7FF.<br><br>    " Extract fractional part "<br>    fractionBits _ allBits bitAnd: 16r000FFFFFFFFFFFFF.<br><br>    " Special cases: infinites and NaN"<br>    exponentBits = 16r7FF ifTrue: [<br>        ^fractionBits = 0<br>            ifTrue: [ aZeroOrOneArgBlock valueWithPossibleArgument: self ]<br>            ifFalse: [ otherZeroOrOneOrTwoArgBlock valueWithPossibleArgument: self and: fractionBits ]].<br><br>    " Unbias exponent: 16r3FF is bias"<br>    exponent _ exponentBits - 16r3FF.<br><br>    " Replace omitted leading 1 in fraction if appropriate"<br>    "If expPart = 0, I am +/-zero or a denormal value. In such cases, no implicit leading bit in mantissa"    <br>    exponentBits = 0<br>        ifTrue: [<br>            mantissa _ fractionBits.<br>            exponent _ exponent + 1 ]<br>        ifFalse: [<br>            mantissa _ fractionBits bitOr: 16r0010000000000000 ].<br><br>    "Evaluate the block"<br>    ^aThreeArgumentBlock value: sign value: exponent value: mantissa</div><div class="gmail_quote"><br></div><div class="gmail_quote"><br></div><div class="gmail_quote"><div>Otherwise, on a 64 bit VM, i would start with significandAsInteger which is a SmallInteger, and play with bitShift: 1 - lowbit...</div><div>But it would need measurements and is probably a bad idea in 32bits.<br></div></div></div><div class="gmail_extra"><br></div></div>