> - { .angle = π * -1.89999999999999991, .sin =
> 0.30901699437494767, .cos = 0.95105651629515353 },
> + { .angle = π * -1.89999999999999991, .sin =
> 0.30901699437494762, .cos = 0.95105651629515353 },That's very odd. Is this using exactly the same compiler and C library on both machines? This is calling the math library 'sin' function for the bulk of the computation, so any tiny variation in library source or compiler version used to build that library could easily have this kind of effect. > This is a native build on amd64/x86_64 both runs, and yet I can't > reproduce it locally. I thought the point of IEEE 754 or whatever it > was was to ensure this sort of thing didn't happen across runs? :) C doesn't guarantee to respect the order of operations in floating point computations, so maybe there was some variation in how the math library was compiled? The two values above differ by only a single ULP. The higher value above is also less accurate than the lower value by a tiny amount; the true answer lies almost exactly between them. One credible alternative would be to write a bc script to generate this table, rather than using a C program. That would also make this reproducible between x86_64 and i386; I'm sure those two targets would produce wildly different answers for these test vectors. To rule out a hardware bug, can we run a single static binary on both physical machines? Build this on one machine, then run on both and compare the results. A hardware bug would be surprising, of course.
#include <stdio.h>
#include <math.h>
volatile double v = -0x1.7e0485cda5e0ap+2; /* -5.9690260418206069203961305902339518070220947265625 */
volatile double sinv = 0x1.3c6ef372fe953p-2; /* 0.309016994374947617796323129368829540908336639404296875 */
/*
* nickle and bc agree that the answer is about
* 0x1.3c6ef372fe9537f49 0.309016994374947645396873930110359227221870944045016832
*
* sometimes x86_64 gets 0x1.3c6ef372fe954p-2 0.3090169943749476733074743606266565620899200439453125
*
* As you can see from the hex numbers above, the correct answer is
* almost exactly between the two values:
*
* correct - 0x1.3c6ef372fe953p-2 = 2.760055080074153e-17
* 0x1.3c6ef372fe954p-2 - correct = 2.79106004305163e-17
*/
int main(void)
{
volatile double s = sin(v);
int ret = 0;
printf("value: ( %.18g %a ) sin(value): ( %.18g %a )\n", v, v, s, s);
if (s != sinv) {
printf("Error: expected ( %.18g %a ) got ( %.18g %a )\n", sinv, sinv, s, s);
ret = 1;
}
return ret;
}
$ cc -static -O2 bug-1086188.c -lm -- -keith
signature.asc
Description: PGP signature

