4 ms·
I used the following C code earlier this year (use at your own peril): https://github.com/nsajko/numericcompfricas/blob/master/check/checker.c#L234 https://gith
by nsajko 6y ago
I used the following C code earlier this year (use at your own peril): https://github.com/nsajko/numericcompfricas/blob/master/check/checker.c#L234 https://github.com/nsajko/numericcompfricas/blob/master/chec...
Distance between 0.0 and -0.0 is taken to be 0. If x or y are NaN, the distance is taken to be the greatest positive value of the return type.
Replace mfloat_t with double. Replace int64 with long or similar.
int64
ud(mfloat_t x, mfloat_t y) {
// Handle NaNs.
if (x != x || y != y) {
return (int64)(~0UL >> 1);
}
union {mfloat_t X; uint64 a;} u1;
union {mfloat_t Y; uint64 b;} u2;
u1.X = x;
u2.Y = y;
uint64 a = u1.a, b = u2.b;
if ((a & (1UL << 63)) == (b & (1UL << 63))) {
// a and b are of the same sign.
a = a - b;
if ((a & (1UL << 63))) {
return -a;
}
return a;
}
return (int64)(a - (1UL << 63) + b);
}
Using memcpy could be more portable than using unions, but I think it doesn't really matter.
EDIT: The Musl libc, for example, also uses unions instead of memcpy: https://git.musl-libc.org/cgit/musl/tree/src/math/nextafterf.c https://git.musl-libc.org/cgit/musl/tree/src/math/nextafterf...