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