Skip to content

Instantly share code, notes, and snippets.

@larryhou
Created August 19, 2022 09:18
Show Gist options
  • Save larryhou/944a1bf73ea6f1beb07b914eaf4ea46d to your computer and use it in GitHub Desktop.
Save larryhou/944a1bf73ea6f1beb07b914eaf4ea46d to your computer and use it in GitHub Desktop.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define HALF_EXPONENT 5
#define HALF_FRACTION (16-HALF_EXPONENT-1)
#define SINGLE_EXPONENT 8
#define SINGLE_FRACTION (32-SINGLE_EXPONENT-1)
#define DOUBLE_EXPONENT 11
#define DOUBLE_FRACTION (64-DOUBLE_EXPONENT-1)
double resolve(double v, int exponent, int fraction) {
auto raw = *(uint64_t *)&v;
auto me = (uint64_t(1)<<DOUBLE_EXPONENT) - 1;
auto mf = (uint64_t(1)<<DOUBLE_FRACTION) - 1;
auto s = (raw >> (DOUBLE_EXPONENT+DOUBLE_FRACTION)) & 1;
auto e = (raw >> DOUBLE_FRACTION & me) - (me>>1);
auto f = 1.0 + double(raw & mf)/mf;
auto nme = (uint64_t(1)<<exponent) - 1;
auto nmf = (uint64_t(1)<<fraction) - 1;
auto ne = e + (nme>>1);
auto nf = static_cast<uint64_t>((f - 1.0) * (nmf+1));
auto layout = s << (exponent + fraction) | ne << fraction | nf;
// auto min = pow(2, 1 - (nme>>1)) * (1.0/(nmf+1));
auto max = pow(2, (nme-1) - (nme>>1))*(1.0+double(nmf)/(nmf+1));
printf("%.8f %.8f %#llx MAX=%.8f [%lld,%llu]\n", v, pow(2, e)*(1.0+double(nf)/(nmf+1)), layout, max, 1 - (nme>>1), (nme-1) - (nme>>1));
return 0;
}
int main(int argc, char* argv[]) {
for (auto i = 1; i < argc; i++)
{
double v = atof(argv[i]);
printf("%.8f %#016llx\n", v, *(uint64_t *)&v);
resolve(v, DOUBLE_EXPONENT, DOUBLE_FRACTION);
resolve(v, SINGLE_EXPONENT, SINGLE_FRACTION);
resolve(v, HALF_EXPONENT, HALF_FRACTION);
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment