6
$\begingroup$

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.

$\endgroup$
3
  • 1
    $\begingroup$ possible dup mathematica.stackexchange.com/a/27540/2079 $\endgroup$ – george2079 Mar 7 '17 at 12:01
  • 4
    $\begingroup$ No, there is a direct calculation of a number of 4 bytes: {b1, b2, b3, b4} >> num. I need a reverse calculation. $\endgroup$ – Kirill Belov Mar 7 '17 at 12:07
  • $\begingroup$ you are correct, I should have just said "related". Its not a trivial matter to reverse the operation. $\endgroup$ – george2079 Mar 7 '17 at 13:00
6
$\begingroup$

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}*)
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.