Created
August 19, 2022 09:18
-
-
Save larryhou/944a1bf73ea6f1beb07b914eaf4ea46d to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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