@@ -246,11 +246,37 @@ class Literal {
246246 }
247247 }
248248
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+
249275 static void printFloat (std::ostream &o, float f) {
250276 if (std::isnan (f)) {
251277 const char *sign = std::signbit (f) ? " -" : " " ;
252278 o << sign << " nan" ;
253- if (uint32_t payload = ~ 0xff800000u & bit_cast< uint32_t > (f)) {
279+ if (uint32_t payload = NaNPayload (f)) {
254280 o << " :0x" << std::hex << payload << std::dec;
255281 }
256282 return ;
@@ -266,7 +292,7 @@ class Literal {
266292 if (std::isnan (d)) {
267293 const char *sign = std::signbit (d) ? " -" : " " ;
268294 o << sign << " nan" ;
269- if (uint64_t payload = ~ 0xfff0000000000000ull & bit_cast< uint64_t > (d)) {
295+ if (uint64_t payload = NaNPayload (d)) {
270296 o << " :0x" << std::hex << payload << std::dec;
271297 }
272298 return ;
@@ -448,7 +474,7 @@ class Literal {
448474 switch (std::fpclassify (rhs)) {
449475 case FP_ZERO:
450476 switch (std::fpclassify (lhs)) {
451- case FP_NAN: return * this ;
477+ case FP_NAN: return Literal ( setQuietNaN (lhs)) ;
452478 case FP_ZERO: return Literal (std::copysign (std::numeric_limits<float >::quiet_NaN (), sign));
453479 case FP_NORMAL: // fallthrough
454480 case FP_SUBNORMAL: // fallthrough
@@ -468,7 +494,7 @@ class Literal {
468494 switch (std::fpclassify (rhs)) {
469495 case FP_ZERO:
470496 switch (std::fpclassify (lhs)) {
471- case FP_NAN: return * this ;
497+ case FP_NAN: return Literal ( setQuietNaN (lhs)) ;
472498 case FP_ZERO: return Literal (std::copysign (std::numeric_limits<double >::quiet_NaN (), sign));
473499 case FP_NORMAL: // fallthrough
474500 case FP_SUBNORMAL: // fallthrough
0 commit comments