[✓] Get hexadecimal representation for a float as a string?

Posted 5 months ago
709 Views
|
7 Replies
|
7 Total Likes
|
 Hello I wonder how I could use Mathematica commands to do the following:An irrational number, ir, (a huge expression as a result of iterating a discrete map) is converted to single precision (Real16) and then to hexadecimal as a string. Example single(ir)=0.25=3e800000 (using matlab).I know single precision is not available on WM 11.3 but Real32, Real64 and Real128 are. As for the hexadecimal representation I have to confess that I could not figure out how to do it even considering, for instance, Real32.Your help is much appreciated.Many thanksEd
7 Replies
Sort By:
Posted 5 months ago
 Would BaseForm[number,16] suffice? If not, please give specifics for the hex format required.
Posted 5 months ago
 Many thanks. BaseForm[0.25,16]=0.4_16 and what I need as output is 3E800000 (note that the number of digits also counts). Example (matlab)format hex;single(0.25)ans =single3e800000endformat hex;double(0.25)ans =3fd0000000000000As far as I know there is no Real16 (single) available in Mathematica. Could it be implemented?
Posted 5 months ago
 I'll start with the assumption that a given nonzero number is a machine double, and we want to show the hex string for either 32 or 64 bit format. We give as parameters the exponent field size and the total number of hex digits for the result. toHex[n_Real, esize_Integer, hlen_Integer] /; Precision[n] === MachinePrecision && n != 0 := Module[ {mant, exp, sgn, bits, hexdigits, rule}, {mant, exp} = RealDigits[n, 2]; mant = Rest[mant]; sgn = If[n > 0, {0}, {1}]; exp = IntegerDigits[exp + 2^(esize - 1) - 2, 2, esize]; bits = PadRight[Flatten[{sgn, exp, mant}], 64]; hexdigits = Take[IntegerDigits[FromDigits[bits, 2], 16, 16], hlen]; rule = Thread[Range[10, 15] -> Characters["abcdef"]]; Apply[StringJoin, Map[ToString, hexdigits /. rule]] ] In the examples, 32 bit floats means 8 hex digits total, and the standard exponent width is 8 bits. toHex[.25, 8, 8] (* Out[174]= "3e800000" *) For 64 bit floats the exponent field is 11 bits. toHex[.25, 11, 16] (* Out[175]= "3fd0000000000000" *) I will add the disclaimer that, unless one is a good speller, it might be unwise even to attempt to hex a decimal...
Posted 5 months ago
 Thank you ever so much. Although I believe function toHex is exactly what I need, I wonder whether you could help me further. a) The hex number just below "3e800000" is "3e7fffff" and just above "3e800001", right? (Considering 32-bit floats). b) I also need to go back from hex to decimal taking into account the precision.
Posted 5 months ago
 The values you give in (a) both look correct to me.
 Not yet fully tested, but this should do the inverse computation. FromHexadecimalString[ss_String] := FromHexadecimalString[ss, {11, MachinePrecision}] FromHexadecimalString[ss_String, {esize_Integer, prec_}] /; esize > 0 && N[prec] > 0 := Module[ {hexdigits = Characters[ss], bits, rule, sgn, exp, mant}, rule = Thread[Characters["abcdef"] -> Range[10, 15]]; hexdigits = Map[ToExpression, Characters[ss] /. rule]; bits = Flatten[Map[IntegerDigits[#, 2, 4] &, hexdigits]]; sgn = If[First[bits] == 0, 1, -1]; {exp, mant} = TakeDrop[Rest[bits], esize]; exp = FromDigits[exp, 2] - 2^(esize - 1) + 2; mant = Total[1/2 + mant. 2^Range[-2, -Length[mant] - 1, -1]]; N[sgn*mant*2^exp, prec] ] /; Complement[Union[Characters[ss]], Join[Characters["abcdef"], Map[ToString, Range[0, 9]]]] === {} Example: FromHexadecimalString["3fd0000000000000"] (* Out[413]= 0.25 *)