1 //
2 // SPDX-License-Identifier: BSD-3-Clause
3 // Copyright Contributors to the OpenEXR Project.
4 //
5
6 #ifdef NDEBUG
7 # undef NDEBUG
8 #endif
9
10 #include "halfLimits.h"
11 #include <assert.h>
12 #include <cmath>
13 #include <iostream>
14 #include "testLimits.h"
15
16 using namespace std;
17
18 namespace
19 {
20
21 float
mypow(int x,int y)22 mypow (int x, int y)
23 {
24 bool negative = false;
25
26 if (y < 0)
27 {
28 negative = true;
29 y = -y;
30 }
31
32 float z = 1;
33
34 while (y > 0)
35 {
36 z *= x;
37 y -= 1;
38 }
39
40 if (negative)
41 z = 1 / z;
42
43 return z;
44 }
45
46 } // namespace
47
48 void
testLimits()49 testLimits()
50 {
51 cout << "values in std::numeric_limits<half>\n";
52
53 cout << "min_exponent\n";
54
55 {
56 half h (mypow (2, numeric_limits<half>::min_exponent - 1));
57 assert (h.isNormalized());
58 }
59
60 {
61 half h (mypow (2, numeric_limits<half>::min_exponent - 2));
62 assert (h.isDenormalized());
63 }
64
65 cout << "max_exponent\n";
66
67 {
68 half h (mypow (2, numeric_limits<half>::max_exponent - 1));
69 assert (h.isNormalized());
70 }
71
72 {
73 half h (mypow (2, numeric_limits<half>::max_exponent));
74 assert (h.isInfinity());
75 }
76
77 cout << "min_exponent10\n";
78
79 {
80 half h (mypow (10, numeric_limits<half>::min_exponent10));
81 assert (h.isNormalized());
82 }
83
84 {
85 half h (mypow (10, numeric_limits<half>::min_exponent10 - 1));
86 assert (h.isDenormalized());
87 }
88
89 cout << "max_exponent10\n";
90
91 {
92 half h (mypow (10, numeric_limits<half>::max_exponent10));
93 assert (h.isNormalized());
94 }
95
96 {
97 half h (mypow (10, numeric_limits<half>::max_exponent10 + 1));
98 assert (h.isInfinity());
99 }
100
101 #if __cplusplus >= 201103L
102
103 cout << "max_digits10\n";
104 assert (numeric_limits<half>::max_digits10 ==
105 std::ceil (numeric_limits<half>::digits * std::log10 (2) + 1));
106
107 cout << "lowest\n";
108 assert (numeric_limits<half>::lowest() == -HALF_MAX);
109
110 #endif
111
112 cout << "ok\n\n" << flush;
113 }
114
115 void
testHalfLimits()116 testHalfLimits()
117 {
118 cout << "values in std::numeric_limits<half>\n";
119
120 // For reference:
121 printf("HALF_DENORM_MIN %g -> 0x%04x\n", (float)HALF_DENORM_MIN, half(HALF_DENORM_MIN).bits());
122 printf("HALF_NRM_MIN %g -> 0x%04x\n", (float)HALF_NRM_MIN, half(HALF_NRM_MIN).bits());
123 printf("HALF_MIN %g -> 0x%04x\n", (float)HALF_MIN, half(HALF_MIN).bits());
124 printf("HALF_MAX %g -> 0x%04x\n", (float)HALF_MAX, half(HALF_MAX).bits());
125 printf("HALF_LOWEST %g -> 0x%04x\n", (float)-HALF_MAX, half(-HALF_MAX).bits());
126 printf("HALF_EPSILON %g -> 0x%04x\n", (float)HALF_EPSILON, half(HALF_EPSILON).bits());
127 printf("half posInf %g -> 0x%04x\n", (float)half::posInf(), half::posInf().bits());
128 printf("half negInf %g -> 0x%04x\n", (float)half::negInf(), half::negInf().bits());
129 printf("half qNan %g -> 0x%04x\n", (float)half::qNan(), half::qNan().bits());
130 printf("half sNan %g -> 0x%04x\n", (float)half::sNan(), half::sNan().bits());
131 printf("numeric_limits<half> min %g -> 0x%04x\n", (float)std::numeric_limits<half>::min(), std::numeric_limits<half>::min().bits());
132 printf("numeric_limits<half> max %g -> 0x%04x\n", (float)std::numeric_limits<half>::max(), std::numeric_limits<half>::max().bits());
133 printf("numeric_limits<half> lowest %g -> 0x%04x\n", (float)std::numeric_limits<half>::lowest(), std::numeric_limits<half>::lowest().bits());
134 printf("numeric_limits<half> epsilon %g -> 0x%04x\n", (float)std::numeric_limits<half>::epsilon(), std::numeric_limits<half>::epsilon().bits());
135 printf("numeric_limits<half> round_error %g -> 0x%04x\n", (float)std::numeric_limits<half>::round_error(), std::numeric_limits<half>::round_error().bits());
136 printf("numeric_limits<half> infinity %g -> 0x%04x\n", (float)std::numeric_limits<half>::infinity(), std::numeric_limits<half>::infinity().bits());
137 printf("numeric_limits<half> quiet_NaN %g -> 0x%04x\n", (float)std::numeric_limits<half>::quiet_NaN(), std::numeric_limits<half>::quiet_NaN().bits());
138 printf("numeric_limits<half> signaling_NaN %g -> 0x%04x\n", (float)std::numeric_limits<half>::signaling_NaN(), std::numeric_limits<half>::signaling_NaN().bits());
139 printf("numeric_limits<half> denorm_min %g -> 0x%04x\n", (float)std::numeric_limits<half>::denorm_min(), std::numeric_limits<half>::denorm_min().bits());
140
141 assert (std::numeric_limits<half>::max() == half(HALF_MAX));
142 assert (std::numeric_limits<half>::min() == half(HALF_NRM_MIN));
143 assert (std::numeric_limits<half>::denorm_min() == half(HALF_DENORM_MIN));
144 assert (std::numeric_limits<half>::lowest() == half(-HALF_MAX));
145 assert (std::numeric_limits<half>::epsilon() == half(HALF_EPSILON));
146 assert (std::numeric_limits<half>::infinity() == half::posInf());
147 assert (std::numeric_limits<half>::quiet_NaN().bits() == half::qNan().bits());
148 assert (std::numeric_limits<half>::signaling_NaN().bits() == half::sNan().bits());
149 assert (std::numeric_limits<half>::infinity() == half::posInf());
150
151 cout << "ok\n\n" << flush;
152 }
153