7
$\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
    Commented Mar 7, 2017 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$ Commented Mar 7, 2017 at 12:07
  • $\begingroup$ you are correct, I should have just said "related". Its not a trivial matter to reverse the operation. $\endgroup$
    – george2079
    Commented Mar 7, 2017 at 13:00

1 Answer 1

8
$\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 and acknowledge you have read our privacy policy.

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