1

I have a C++ cross-compiler. It produces some floating point code that, at runtime, may generate NaN. On my host platform I want to prepare target-aware "gold" testing results. These will be compared against printf output generated on the target platform, notably involving those floating results.

On any x86 platform, printf("%g\n", 0.0 / 0.0); produces -nan. On just about any other platform it produces nan. This is because IEEE 754 does not specify the sign bit for NaN. Intel chose to set the sign bit to one, every other architecture of which I am aware sets it to zero.

std::quiet_NaN is not useful. It always returns a bit pattern with a zero sign bit on all platforms.

I was hoping that GCC's "Target Description Macros and Functions" would have something appropriate, but, so far, I have found nothing.

John Yates
  • 1,027
  • 1
  • 7
  • 18

1 Answers1

0

It sounds like you're looking for a way to generate a consistent NaN value that takes into account the sign bit and works across multiple platforms. One approach you could try is to use the bit pattern of NaN values that have a positive or negative sign bit, depending on the target platform, and then cast that bit pattern to a floating-point value. you could define a macro that generates a NaN value with a positive or negative sign bit, depending on the target platform.

#if defined(__x86_64__)
#define TARGET_NAN_POSITIVE UINT64_C(0x7ff8000000000000)
#define TARGET_NAN_NEGATIVE UINT64_C(0xfff8000000000000)
#elif defined(__ARM_ARCH_ISA_THUMB) || defined(__ARM_ARCH_ISA_ARM)
#define TARGET_NAN_POSITIVE UINT32_C(0x7fc00000)
#define TARGET_NAN_NEGATIVE UINT32_C(0xffc00000)
#else
#error "Unsupported architecture"
#endif

double get_target_nan(bool positive) {
    uint64_t nan_bits = positive ? TARGET_NAN_POSITIVE : TARGET_NAN_NEGATIVE;
    return *reinterpret_cast<double*>(&nan_bits);
}

you can use this function to generate.

double my_nan = get_target_nan(/*positive=*/true);
printf("%g\n", my_nan);  // prints -nan on x86, nan on other platforms
곽지훈
  • 56
  • 1