I can do this by writing a binary file (see below for two examples),
then using the Unix tool 'od' to display the hex data. But is there
any way of getting this in Mathematica directly?
You might note in the example below, writing out E and Exp[1.0] causes
a difference of one bit in the binary file written. So Mathematica 7
on SPARC shows exactly the same behavior as Sage and a simple C
program.
As a related question, is there anything which can show the IEEE 754
representation of a machine precision floating point number - i.e. the
values of 's', 'c' and 'q' in the equation below?
(-1)^s × c × 2^q
Dave
drkirkby@swan:[~] $ math
Mathematica 7.0 for Sun Solaris SPARC (64-bit)
Copyright 1988-2009 Wolfram Research, Inc.
In[1]:= BinaryWrite["exp1.dat",Exp[1.0],"Real64"]
Out[1]= exp1.dat
In[2]:= !od -t x2 exp1.dat
0000000 4005 bf0a 8b14 576a
0000010
In[2]:= BinaryWrite["E.dat",E,"Real64"]
Out[2]= E.dat
In[3]:= !od -t x2 E.dat
0000000 4005 bf0a 8b14 5769
0000010
You can always import the output back into Mathematica:
In[1]:= IntegerString[
ToCharacterCode@ ExportString[Exp[1.], "Real64"],
16, 2]
Out[1]= {"69", "57", "14", "8b", "0a", "bf", "05", "40"}
Or, assuming the IEEE 754 double precision format, you can do it like
this:
In[2]:= Module[{x = Exp[1.], m, e, bits},
If[x == 0.,
StringJoin@ ConstantArray["0", 16],
{m, e} = MantissaExponent[x, 2];
bits = Flatten@ {UnitStep[-x],
First@ RealDigits[e + 1022, 2, 11, 10],
First@ RealDigits[m, 2, 52, -2]};
IntegerString[FromDigits[bits, 2], 16, 16]]]
Out[2]= "4005bf0a8b145769"
In[3]:= StringJoin@ Reverse@ %% === %
Out[3]= True
Maxim Rytin
m...@inbox.ru
Can do this directly with RealDigits. It operates on the absolute
value of a given real. Which is no hardship, since your sign bit value
is obtained via Sign.
In[86]:= {digits, expon} = RealDigits[Exp[1.], 2]
Out[86]= {{1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1,
0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0,
1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1}, 2}
To get your c value, just treat the digits as bits of an integer:
In[88]:= c = FromDigits[digits, 2]
Out[88]= 6121026514868073
Your exponent is then found as the length of the bit string, less the
exponent given above. This is because the representation of RealDigits
works with a mantissa between 1/2 and 1 (closed interval on the left,
open on the right).
In[89]:= q = expon - Length[digits]
Out[89]= -51
In[91]:= N[c*2^q] - Exp[1.0]
Out[91]= 0.
For more detailed sort of work involving Mathematica's significance
arithmetic, one might instead use NumericalMath`$NumberBits[]. It
returns a list of the form
{sign,good bits, uncertain bits (can regard as guard bits), exponent
based on mantissa as described above}.
In[15]:= NumericalMath`$NumberBits[N[-111/7, 16]]
Out[15]= {-1, {1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1,
0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1,
1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1}, {1, 0, 1, 1, 0, 1, 1, 0, 1, 1,
0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0,
1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1,
0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0,
1, 1}, 4}
Daniel Lichtblau
Wolfram Research
> > As a related question, is there anything which can show the IEEE 754
> > representation of a machine precision floating point number - i.e. the
> > values of 's', 'c' and 'q' in the equation below?
>
> > (-1)^s × c × 2^q
>
> > Dave
> > [...]
>
> Can do this directly with RealDigits. It operates on the absolute
> value of a given real. Which is no hardship, since your sign bit value
> is obtained via Sign.
>
> In[86]:= {digits, expon} = RealDigits[Exp[1.], 2]
> Out[86]= {{1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1,
> 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0,
> 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1}, 2}
>
> To get your c value, just treat the digits as bits of an integer:
>
> In[88]:= c = FromDigits[digits, 2]
> Out[88]= 6121026514868073
<SNIP>
Thank you very much Daniel, it was most helpful.
drkirkby@swan:[~] $ cat RealToIEEE754.m
RealToIEEE754[x_]:=Block[{s,digits,expon,c,q},
s=Sign[x];
{digits,expon}=RealDigits[x,2];
c = FromDigits[digits, 2] ;
q = expon - Length[digits] ;
{s,c,q}
]
drkirkby@swan:[~] $ math
Mathematica 7.0 for Sun Solaris SPARC (64-bit)
Copyright 1988-2009 Wolfram Research, Inc.
In[1]:= <<RealToIEEE754.m
In[2]:= RealToIEEE754[Exp[1.]]
Out[2]= {1, 6121026514868074, -51}
Something tells me you did not produce that example on a SPARC, as not
surprisingly, I get a slightly different result from you.
Dave