@@ -246,11 +246,37 @@ class Literal {
246
246
}
247
247
}
248
248
249
+ static uint32_t NaNPayload (float f) {
250
+ assert (std::isnan (f) && " expected a NaN" );
251
+ // SEEEEEEE EFFFFFFF FFFFFFFF FFFFFFFF
252
+ // NaN has all-one exponent and non-zero fraction.
253
+ return ~0xff800000u & bit_cast<uint32_t >(f);
254
+ }
255
+
256
+ static uint64_t NaNPayload (double f) {
257
+ assert (std::isnan (f) && " expected a NaN" );
258
+ // SEEEEEEE EEEEFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF
259
+ // NaN has all-one exponent and non-zero fraction.
260
+ return ~0xfff0000000000000ull & bit_cast<uint64_t >(f);
261
+ }
262
+
263
+ static float setQuietNaN (float f) {
264
+ assert (std::isnan (f) && " expected a NaN" );
265
+ // An SNaN is a NaN with the most significant fraction bit clear.
266
+ return bit_cast<float >(0x00400000u | bit_cast<uint32_t >(f));
267
+ }
268
+
269
+ static double setQuietNaN (double f) {
270
+ assert (std::isnan (f) && " expected a NaN" );
271
+ // An SNaN is a NaN with the most significant fraction bit clear.
272
+ return bit_cast<double >(0x0008000000000000ull | bit_cast<uint64_t >(f));
273
+ }
274
+
249
275
static void printFloat (std::ostream &o, float f) {
250
276
if (std::isnan (f)) {
251
277
const char *sign = std::signbit (f) ? " -" : " " ;
252
278
o << sign << " nan" ;
253
- if (uint32_t payload = ~ 0xff800000u & bit_cast< uint32_t > (f)) {
279
+ if (uint32_t payload = NaNPayload (f)) {
254
280
o << " :0x" << std::hex << payload << std::dec;
255
281
}
256
282
return ;
@@ -266,7 +292,7 @@ class Literal {
266
292
if (std::isnan (d)) {
267
293
const char *sign = std::signbit (d) ? " -" : " " ;
268
294
o << sign << " nan" ;
269
- if (uint64_t payload = ~ 0xfff0000000000000ull & bit_cast< uint64_t > (d)) {
295
+ if (uint64_t payload = NaNPayload (d)) {
270
296
o << " :0x" << std::hex << payload << std::dec;
271
297
}
272
298
return ;
@@ -448,7 +474,7 @@ class Literal {
448
474
switch (std::fpclassify (rhs)) {
449
475
case FP_ZERO:
450
476
switch (std::fpclassify (lhs)) {
451
- case FP_NAN: return * this ;
477
+ case FP_NAN: return Literal ( setQuietNaN (lhs)) ;
452
478
case FP_ZERO: return Literal (std::copysign (std::numeric_limits<float >::quiet_NaN (), sign));
453
479
case FP_NORMAL: // fallthrough
454
480
case FP_SUBNORMAL: // fallthrough
@@ -468,7 +494,7 @@ class Literal {
468
494
switch (std::fpclassify (rhs)) {
469
495
case FP_ZERO:
470
496
switch (std::fpclassify (lhs)) {
471
- case FP_NAN: return * this ;
497
+ case FP_NAN: return Literal ( setQuietNaN (lhs)) ;
472
498
case FP_ZERO: return Literal (std::copysign (std::numeric_limits<double >::quiet_NaN (), sign));
473
499
case FP_NORMAL: // fallthrough
474
500
case FP_SUBNORMAL: // fallthrough
0 commit comments