Pointer-based Binary Heaps
stackoverflow.com1 pointsby ambrop71 comments
#include <math.h>
#include <stdint.h>
#include <assert.h>
#include <stdio.h>
#include <inttypes.h>
int main()
{
float x = (float)-INFINITY;
uint64_t count = 1;
while (x != (float)INFINITY) {
float y = nextafterf(x, (float)INFINITY);
assert(y != x);
x = y;
++count;
}
printf("Found %" PRIu64 " floats.\n", count);
return 0;
}
$ gcc -std=c99 -O3 a.c -lm -o a
$ ./a
Found 4278190081 floats.
(a little bit harder for doubles) #pragma STDC FENV_ACCESS ON
#include <stdio.h>
#include <stdint.h>
#include <fenv.h>
int main()
{
fesetround(FE_DOWNWARD);
printf("%f\n", (double)UINT64_MAX);
fesetround(FE_UPWARD);
printf("%f\n", (double)UINT64_MAX);
return 0;
}
$ gcc -std=c99 -frounding-math x.c -lm
$ ./a.out
18446744073709551616.000000
18446744073709551616.000000
In both cases it rounded up. bool double_to_uint64 (double x, uint64_t *out)
{
double y = trunc(x);
if (y >= 0.0 && y < ldexp(1.0, 64)) {
*out = y;
return true;
} else {
return false;
}
}
If you need different rounding behavior, just change trunc() to round(), floor() or ceil(). Note that it is important that the result is produced by converting the rounded double (y) to an integer type, not the original value (x).