Created
April 12, 2017 01:37
-
-
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.
This file contains 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 <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