# Convert real number to IBM 32 Float (not IEEE)

How can I convert real number to IBM 32 Float? I think how to do it with RealDigits[], IntegerDigits[] and FromDigits[].

IBM32FloatSignBit =
Function[{num}, UnitStep[-num]];

IBM32FloatExpBits =
Function[{num}, IntegerDigits[RealDigits[num, 16][[-1]] + 64, 2, 7]];

IBM32FloatFractionBits =
Function[{num}, IntegerDigits[RealDigits[num, 16][[1, 1 ;; 6]], 2, 4]];


And the function that will be to convert real number:

IBM32FloatBits =
Function[{num},
FromDigits[#, 2]& /@
Partition[Flatten @ {
IBM32FloatSignBit[num],
IBM32FloatExpBits[num],
IBM32FloatFractionBits[num]
}, {8}]
]

(* for (256.0^3 - 1.0)/256.0^3 return {64, 255, 255, 255} *)


But this way not good. For the large array of numbers function works slowly. Important, that this function will be unpacking array that has been packing. How to avoid this and speed up the reverse conversion to bytes? How to do it without using RealDigits and FromDigits? This functions does not support in Compile.

• possible dup mathematica.stackexchange.com/a/27540/2079 Commented Mar 7, 2017 at 12:01
• No, there is a direct calculation of a number of 4 bytes: {b1, b2, b3, b4} >> num. I need a reverse calculation. Commented Mar 7, 2017 at 12:07
• you are correct, I should have just said "related". Its not a trivial matter to reverse the operation. Commented Mar 7, 2017 at 13:00

### Compiled solution

I found this solutions.

ToIBM32Float =
Compile[{{number, _Real}},
Module[{sign, exp, firstbits, fractbits},

(* sign of the nimber *)
sign = UnitStep[number];

(* 16-th exponent *)
exp = Ceiling[Log[16, Abs[number]]];

firstbits = If[sign == 0,
BitOr[exp + 64, 128],
exp + 64
];
fractbits = IntegerDigits[Floor[16.0^(-exp) number 256.0^3], 256];
Join[{firstbits}, fractbits]
]
];

ToIBM32Float[(256.0^3 - 1.0)/256.0^3]

(* {64, 255, 255, 255} *)


Time measurements:

RepeatedTiming[Do[ToIBM32Float[(256.0^3 - 1.0)/256.0^3], {1000}]]
RepeatedTiming[Do[IBM32FloatBits[(256.0^3 - 1.0)/256.0^3], {1000}]]

(*{0.00207, Null}*)
(*{0.0295, Null}*)