5
#define pack754_32(f) (pack754((f), 32, 8))
6
#define pack754_64(f) (pack754((f), 64, 11))
7
#define unpack754_32(i) (unpack754((i), 32, 8))
8
#define unpack754_64(i) (unpack754((i), 64, 11))
10
uint64_t pack754(long double f, unsigned bits, unsigned expbits)
14
long long sign, exp, significand;
15
unsigned significandbits = bits - expbits - 1; // -1 for sign bit
17
if (f == 0.0) return 0; // get this special case out of the way
19
// check sign and begin normalization
20
if (f < 0) { sign = 1; fnorm = -f; }
21
else { sign = 0; fnorm = f; }
23
// get the normalized form of f and track the exponent
25
while(fnorm >= 2.0) { fnorm /= 2.0; shift++; }
26
while(fnorm < 1.0) { fnorm *= 2.0; shift--; }
29
// calculate the binary form (non-float) of the significand data
30
significand = fnorm * ((1LL<<significandbits) + 0.5f);
32
// get the biased exponent
33
exp = shift + ((1<<(expbits-1)) - 1); // shift + bias
35
// return the final answer
36
return (sign<<(bits-1)) | (exp<<(bits-expbits-1)) | significand;
39
long double unpack754(uint64_t i, unsigned bits, unsigned expbits)
44
unsigned significandbits = bits - expbits - 1; // -1 for sign bit
46
if (i == 0) return 0.0;
48
// pull the significand
49
result = (i&((1LL<<significandbits)-1)); // mask
50
result /= (1LL<<significandbits); // convert back to float
51
result += 1.0f; // add the one back on
53
// deal with the exponent
54
bias = (1<<(expbits-1)) - 1;
55
shift = ((i>>significandbits)&((1LL<<expbits)-1)) - bias;
56
while(shift > 0) { result *= 2.0; shift--; }
57
while(shift < 0) { result /= 2.0; shift++; }
60
result *= (i>>(bits-1))&1? -1.0: 1.0;
67
float f = 3.1415926, f2;
68
double d = 3.14159265358979323, d2;
73
f2 = unpack754_32(fi);
76
d2 = unpack754_64(di);
78
printf("float before : %.7f\n", f);
79
printf("float encoded: 0x%08" PRIx32 "\n", fi);
80
printf("float after : %.7f\n\n", f2);
82
printf("double before : %.20lf\n", d);
83
printf("double encoded: 0x%016" PRIx64 "\n", di);
84
printf("double after : %.20lf\n", d2);