Skip to content

Instantly share code, notes, and snippets.

@sam-the-enby
Created April 12, 2017 01:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sam-the-enby/10f0adca2bc8b5c0e370f3c92712da07 to your computer and use it in GitHub Desktop.
Save sam-the-enby/10f0adca2bc8b5c0e370f3c92712da07 to your computer and use it in GitHub Desktop.
A c program that will decompose an IEEE-754 Double Precision Floating Point number into its constituent parts. ONLY WORKS ON LITTLE-ENDIAN SYSTEMS.
#include <stdint.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
//NOTE: only works on little-endian systems
union dub
{
double real;
uint64_t whole;
uint32_t half[2];
uint16_t quarter[4];
uint8_t eighths[8];
};
int main(int argc, char *argv[])
{
if(argc<2)
{
puts("Error: must supply floating point value.");
exit(1);
}
union dub d;
sscanf(argv[1],"%lf",&d.real);
printf("Real value: %f %a\n",d.real,d.real);
printf("Long value: %lu\n",d.whole);
printf("Int values: %u %u\n",d.half[1],d.half[0]);
printf("Short values: %u %u %u %u\n",d.quarter[3],d.quarter[2],d.quarter[1],d.quarter[0]);
printf("Byte values: %u %u %u %u %u %u %u %u\n",d.eighths[7],d.eighths[6],d.eighths[5],d.eighths[4],d.eighths[3],d.eighths[2],d.eighths[1],d.eighths[0]);
printf("----------\nParts: sign: %d, ", ((d.eighths[7] & 0x80)/*==0x80*/?1:0));
int _exp = ((d.eighths[7] & 0x7F) << 4) | ((d.eighths[6] & 0xF0) >> 4);
printf("expt: %4d (raw %5d minus offset 1023), ", _exp-1023, _exp);
long long mant;
mant |=(d.eighths[6]&0x0F); mant <<=8;
mant |=(d.eighths[5]&0xFF); mant <<=8;
mant |=(d.eighths[4]&0xFF); mant <<=8;
mant |=(d.eighths[3]&0xFF); mant <<=8;
mant |=(d.eighths[2]&0xFF); mant <<=8;
mant |=(d.eighths[1]&0xFF); mant <<=8;
mant |=(d.eighths[0]&0xFF);// mant <<=8;
union dub dd;
sscanf(argv[1],"%lf",&dd.real);
dd.whole&=0x000fffffffffffff;
dd.whole|=(0x3ff0000000000000);
printf("mant: %f (%lld, 0x%016llX)\n", dd.real, mant, mant);
printf("Hex: 0x");
for(int i=7; i>-1; i--)
{
printf("%02hhx",d.eighths[i]);
}
puts("");
int qqq=0;
for(int i=0; i<8; i++)
{
printf("%8d",qqq++);
}
puts("");
for(int i=7; i>-1; i--)
{
for(int q=7; q>-1; q--)
{
if((i==7 && q==6) || (i==6 && q==3))
{
printf("\e[3%dm",i-1);
}
printf("%c",(d.eighths[i]>>q)%2==0?'0':'1');
}
}
printf("\e[0m\n");
printf("-1^(%d) * 2^(%d) * %f = %f\n",(d.eighths[7]&0x80)>>7,_exp-1023,dd.real,(dd.real * exp2(_exp-1023) * (d.eighths[7]&0x80?-1:1)));
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment