Message Boards Message Boards

Convert floating point representation to any scientific notation & back

GROUPS:

Hello guys,

Is there any inbuilt function where I can input a value that is represented in floating point format (Sign, Exp, Mantissa) and somehow obtain its true value? The reason why I'm asking this is because I have an implementation in VHDL that outputs values in fp format, and would like to convert it in Mathematica to a decimal value (or any other scientific format). By doing this I can compare the precision from my VHDL implementation with mathematica.

Cheers!

PS. I've searched for a similar function in google success, hence I'm asking here.

POSTED BY: Hussein Ezzeddine
Answer
3 years ago

It's hard to know exactly what you are asking for here. I'll make an assumption that you have a list of floating point sets {Sign, Exp, Mantiss}. If so, you could use replacement:

In[4]:= fps = {{-1,-4,1.2345},{1,2,9.8765}}
Out[4]= {{-1,-4,1.2345},{1,2,9.8765}}
In[5]:= fps/.{a_,b_,c_}->a c 10^b
Out[5]= {-0.00012345,987.65}

The replacement rule at In[5] simply places the numbers in their proper location.

EDIT: note that I assumed an exponent base of 10 and I used mantissa that are themselves decimals and this is not a straight from binary code, which would be implementation specific anyhow.

POSTED BY: Jason Grigsby
Answer
3 years ago

Do you mean you have IEEE floating point numbers? Or some proprietary format? Mathematica can use BinaryRead for many standard formats. Proprietary formats can often be dealt with by pattern substitutions which get them into a readable format. Perhaps you could post an example of such a number, or describe it more exactly.

POSTED BY: David Keith
Answer
3 years ago

My bad, I should have given an example as well.

I have some value displayed in double precision fp format:

0.01111111111.1001111110011001100110011001100110011001100110011010 

OBS. the dots are not supposed to be there, I've just put them there manually to help you distinguish the different parts (S, Exp, M).

And would like to convert it into lets say, scientific form.

It doesn't seem possible to use the replace function (/.) with binary numbers. Tried to do something similar:

In[101]:= fps = {0 , 011, 1111}

Out[101]= {0, 11, 1111}

In[107]:= fps /. {a_, b_, c_} -> 2^^b

During evaluation of In[107]:= General::digit: Digit at position 1 in b is too large to be used in base 2. >>

Cheers

POSTED BY: Hussein Ezzeddine
Answer
3 years ago

Hi Hussein,

The format you provide appears to be the IEEE Double. (See http://en.wikipedia.org/wiki/Double-precision_floating-point_format )
It would certainly be possible to read a file of such data as bytes and convert to characters and then try to convert it yourself to a Real in Mathematica. However, you would need to pay attention to the exact way in which the number is encoded.

It is not clear in your post exactly how you got from a binary representation to the presumably base 2 number representation as you show. In Mathematica, what you have is a decimal number that happens to make use of only 1 and 0 digits.

I suspect however that your VHDL tool is outputting binary doubles, and it would be much easier to read them into Mathematica using binary IO. There are a few issues in this. One is byte order, but that is unlikely to matter if you're working in Windows. The other is that you need to understand the exact order in which numbers of various types are written, and read the file with those types specified. Look up "Binary Data" in the help system to see all the types available.

I attach a notebook which gives examples of writing and then reading binary files of numbers. Put it in a directory of your choice and it will write and read files in the same directory.

Kind regards, David

Attachments:
POSTED BY: David Keith
Answer
3 years ago

Thanks David, especially for the part descirbing how to read and write to documents. That will make the whole process much easier. I believe that Yuki's solution, using the functions to translate floating point (base 2) into decimals (base 10) will be much more simple.

So thanks to both of you guys, really appreciated!

Cheers

POSTED BY: Updating Name
Answer
3 years ago

I show interconversion with floating point and real number.

(* convert to IEEE 754 single precision floating point  binary seqence (length: 32) from number *)
real32Digits[x_] := 
 IntegerDigits[
  First[ImportString[ExportString[x, "Real32"], "UnsignedInteger32"]],
   2, 32]

(* generate {Sign, Exp, Mantissa} list from Real 32 binary sequence (except special number) *)
real32Format[li_] :=
 {If[First[li] === 0, 1, -1],
  FromDigits[Take[li, {2, 9}], 2] - 2^7 + 1,
  FromDigits[{Join[{1}, Take[li, {10, 32}]], 1}, 2]}

(* convert to real number from Real32 binary sequence *)
fromReal32Digits[li_] := First[ImportString[ExportString[FromDigits[li, 2], "UnsignedInteger32"], "Real32"]]

Example:

In[1] := real32Digits[-118.625]
Out[1] := {1, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 0, 0, 0}

In[2]:= real32Format[%]
Out[2] := {-1, 6, 949/512}

In[3] := fromReal32Digits[%%]
Out[3] := -118.625

Mathematica supports floating point representations; Real16, Real32, Real64, and Real128.

refer to

IEEE floating point - Wikipedia, the free encyclopedia

Binary Data—Wolfram Mathematica 9 Documentation

appendix: Coloring parts of floating point sequence

nLi = IntegerDigits[First[ImportString[ExportString[-118.625, "Real32"], "UnsignedInteger32"]], 2, 32]
sgnLi = Take[nLi, 1]; (* Sign *)
eLi = Take[nLi, {2, 9}]; (* Exp *)
sLi = Take[nLi, {10, 32}]; (* Mantissa *)
Grid[{Join @@ {Item[#, Background -> LightBlue] & /@ sgnLi, 
    Item[#, Background -> LightGreen] & /@ eLi, 
    Item[#, Background -> LightRed] & /@ sLi}}]
POSTED BY: Yu(u)ki IWABUCHI
Answer
3 years ago

Thanks Yuki, exactly what I was looking for. Highly appreciated.

Cheers

POSTED BY: Hussein Ezzeddine
Answer
3 years ago

Group Abstract Group Abstract