I have a simple test application below which prints a double
and a long double
using printf.
#include <stdio.h>
int main()
{
printf("%f\n", 1.2345675);
printf("%Lf\n", 1.2345675L);
return 0;
}
$ gcc main.c
$ ./a.out
1.234568 1.234567
If I run this under valgrind
, the long double
is printed as if it were a double
.
$ valgrind --quiet ./a.out
1.234568 1.234568 <------- why not 1.234567?
I am using valgrind 3.19.0
$ valgrind --version
valgrind-3.19.0
long double
support under valgrind?Edit:
Per request by @chux I have added printing using %a
/ %La
(the details of which can be found in this SO answer)
Unfortunately I still get different results:
Without valgrind:
0x1.3c0c9d9d3458dp+0
0x9.e064ece9a2c669p-3
With valgrind:
0x1.3c0c9d9d3458dp+0
0x9.e064ece9a2c68p-3
The long double
still loses precision:
0x9.e064ece9a2c669p-3 (native x86-64)
0x9.e064ece9a2c68p-3 (valgrind)
^^
This is normal
Valgrind's floating-point emulation may treat long double as a double under the hood. This behavior occurs because the long double type requires extended precision (80-bit or higher, depending on the architecture), which valgrind doesn't fully emulate by default. Different Behavior with and without valgrind:
Without valgrind, your application uses the native hardware floating-point unit (FPU), which correctly handles long double precision. Under valgrind, the FPU instructions are emulated, and due to limitations or bugs in the emulation layer, long double values may be truncated to double.
Valgrind has the following limitations in its implementation of x86/AMD64 floating point relative to IEEE754.
Precision: There is no support for 80 bit arithmetic. Internally, Valgrind represents all such "long double" numbers in 64 bits, and so there may be some differences in results. Whether or not this is critical remains to be seen. Note, the x86/amd64 fldt/fstpt instructions (read/write 80-bit numbers) are correctly simulated, using conversions to/from 64 bits, so that in-memory images of 80-bit numbers look correct if anyone wants to see.
The impression observed from many FP regression tests is that the accuracy differences aren't significant. Generally speaking, if a program relies on 80-bit precision, there may be difficulties porting it to non x86/amd64 platforms which only support 64-bit FP precision. Even on x86/amd64, the program may get different results depending on whether it is compiled to use SSE2 instructions (64-bits only), or x87 instructions (80-bit). The net effect is to make FP programs behave as if they had been run on a machine with 64-bit IEEE floats, for example PowerPC. On amd64 FP arithmetic is done by default on SSE2, so amd64 looks more like PowerPC than x86 from an FP perspective, and there are far fewer noticeable accuracy differences than with x86.