/tmp > cat test-ld.c #include <assert.h> #include <stdint.h> static long double max_d = 0xFFFFFFFFFFFFFFFF; static inline long double to_double(uint64_t value) { const long double fvalue = value; return fvalue / max_d; } int main() { long double x = to_double(0xFFFFFFFFFFFFFFFF); assert(x >= 0); assert(x <= 1); return 0; } /tmp > gcc -o test test-ld.c /tmp > ./test /tmp > valgrind ./test ==999419== Memcheck, a memory error detector ==999419== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al. ==999419== Using Valgrind-3.16.1 and LibVEX; rerun with -h for copyright info ==999419== Command: ./test ==999419== test: test-ld.c:14: main: Assertion `x <= 1' failed. ==999419== ==999419== Process terminating with default action of signal 6 (SIGABRT): dumping core ==999419== at 0x48C61A1: raise (raise.c:50) ==999419== by 0x48AF537: abort (abort.c:79) ==999419== by 0x48AF420: __assert_fail_base.cold (assert.c:92) ==999419== by 0x48BEA51: __assert_fail (assert.c:101) ==999419== by 0x1091C9: main (in /tmp/test) ==999419== ==999419== HEAP SUMMARY: ==999419== in use at exit: 0 bytes in 0 blocks ==999419== total heap usage: 2 allocs, 2 frees, 154 bytes allocated ==999419== ==999419== All heap blocks were freed -- no leaks are possible ==999419== ==999419== For lists of detected and suppressed errors, rerun with: -s ==999419== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) zsh: abort (core dumped) valgrind ./test /tmp > valgrind --version valgrind-3.16.1 /tmp > uname -m x86_64 /tmp >
Please see https://www.valgrind.org/docs/manual/manual-core.html#manual-core.limits and in particular the section on x86 floating point. Valgrind does not implement the extended 80 bit precision of the x87 instructions so long double is equivalent to double when running under valgrind.