float32
./code/float32/main.cc
1#include <assert.h>
2#include <cmath>
3#include <iostream>
4#include <limits>
5
6// 1 sign
7// 8 exp
8// 23 significand, or mantissa
9//
10// bias is 127
11
12bool IsInfinity(float x) {
13 // exp: all 1
14 // significant: all 0
15 // when sign is 0 -> positive infinity
16 // when sign is 1 -> negative infinity
17 union {
18 float f;
19 int32_t i;
20 } w;
21 w.f = x;
22 int32_t exp = (w.i >> 23) & 0xff;
23 int32_t significand = w.i & 0x7fffff;
24 return exp == 0xff && significand == 0;
25}
26
27bool IsNaN(float x) {
28 // exp: all 1
29 // significant: non-zero
30 //
31 // quiet nan: the leftmost significand is 1
32 // signaling nan: the leftmost significand is 0
33 union {
34 float f;
35 int32_t i;
36 } w;
37 w.f = x;
38 int32_t exp = (w.i >> 23) & 0xff;
39 int32_t significand = w.i & 0x7fffff;
40 return exp == 0xff && significand != 0;
41}
42
43bool IsDenormalized(float x) {
44 // exp, all 0
45 // significand is not 0
46 union {
47 float f;
48 int32_t i;
49 } w;
50 w.f = x;
51 int32_t exp = (w.i >> 23) & 0xff;
52 int32_t significand = w.i & 0x7fffff;
53 return exp == 0 && significand != 0;
54}
55
56int32_t main() {
57 float pos_inf = std::numeric_limits<float>::infinity(); // 0x7f80_0000
58 float neg_inf = -std::numeric_limits<float>::infinity(); // 0xff80_0000
59 assert(IsInfinity(pos_inf));
60 assert(IsInfinity(neg_inf));
61 assert(std::fpclassify(pos_inf) == FP_INFINITE);
62 assert(std::fpclassify(neg_inf) == FP_INFINITE);
63
64 float quiet_nan = std::numeric_limits<float>::quiet_NaN(); // 0x7fc0_0000
65 float signaling_nan =
66 std::numeric_limits<float>::signaling_NaN(); // 0x7fa0_0000
67
68 assert(IsNaN(quiet_nan));
69 assert(IsNaN(signaling_nan));
70 assert(std::fpclassify(quiet_nan) == FP_NAN);
71 assert(std::fpclassify(signaling_nan) == FP_NAN);
72
73 // the smallest positive normal value
74 //
75 // Note the bias is 127
76 float d1 = std::numeric_limits<float>::min(); // 0x80_0000, 1/(1<<126)
77
78 float d2 = std::numeric_limits<float>::min() / 2; // 0x40_0000
79
80 assert(std::fpclassify(d1) == FP_NORMAL);
81 assert(std::fpclassify(d2) == FP_SUBNORMAL);
82 assert(IsDenormalized(d1) == false);
83 assert(IsDenormalized(d2) == true);
84}
See also