[squeakdev] ASN.1 Floats
Bert Freudenberg
bert at freudenbergs.de
Thu Oct 12 15:46:25 UTC 2017
On Thu, Oct 12, 2017 at 11:36 AM, Alan Pinch <alan.c.pinch at gmail.com> wrote:
> 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:
>
> 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, PLUSINFINITY,
> 0, and MINUSINFINITY, are also allowed.
>
> Here are some sample values:
>
>
>  09 00 = 0 (zero)
>  09 01 40 = +INF (infinity)
>  09 01 41 = INF
>  09 08 03 2b 31 2e 30 65 2b 30 = "+1.0e+0" = 1.0 (exact decimal)
>  09 05 80 fe 55 55 55 = 1398101.25 (binary, 0x555555 * 2^2)
>  09 06 83 00 fc 00 00 01 = 0.0625 (binary, 0x000001 * 2^4)
>
> I have not parsed out these samples into these components so it's greek.
>
Well it's not the same issue as 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.
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:
1398101.25 significand
=> 1.3333332538604736
1398101.25 exponent
=> 20
1.3333332538604736 timesTwoPower: 20
=> 1.39810125e6
1398101.25 = 1.39810125e6
=> true
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:
x := 1398101.25.
mantissa := x significand.
exponent := x exponent.
base := 2.
[mantissa fractionPart isZero] whileFalse:
[mantissa := mantissa * base.
exponent := exponent  1].
{mantissa asInteger hex. base. exponent}
#('16r555555' 2 2)
... which matches your example.
I'm sure Nicolas will have a much more efficient formula, but this would
work :)
 Bert 
 next part 
An HTML attachment was scrubbed...
URL: <http://lists.squeakfoundation.org/pipermail/squeakdev/attachments/20171012/f01dc0af/attachment.html>
More information about the Squeakdev
mailing list
