功能:互轉浮點數與二進制表示法
/* ieee754.c * Authors: Aaron Liao * Last updated: 2010/12/29 * IEEE754 sample code * LICENSE: GPL * 32 bits: [1][8][23] * 64 bits: [1][11][52] */ #include <strings.h> #include <string.h> #include <stdio.h> int ieee754(char *data, double real) { int exp=0, i=0, exp_tmp; double cal, frag_tmp; char buf[32]; bzero(buf, sizeof(buf)); cal = real; /* get sign */ if( cal < 0 ){ buf[0] = 1; cal *= (double) -1; } else { buf[0] = 0; } /* get exp */ while( cal >= 1.0 ) { cal /= 2; exp++; } for( i=8, exp_tmp=1; i>0; i--){ if( (exp & exp_tmp) ) { buf[i] = 1; } else { buf[i] = 0; } exp_tmp *=2 ; } /* get fraction */ for(i=9, frag_tmp = (double) 1/2; i< 32; i++) { if( (cal - frag_tmp) >= 0 ){ buf[i] = 1; cal = (double) cal - (double) frag_tmp; } else { buf[i] = 0; } frag_tmp /= (double) 2; } /* To ascii */ for(i=0; i<32; i++) { buf[i] += '0'; } strncpy(data, buf, 32); return 0; } double rev_ieee754(char *buf) { int exp=0, i=0, exp_tmp, sign; double real, frag_tmp; int len = 32; /* get sign */ if( buf[0] == '1' ){ sign = -1; } else { sign = 1; } /* get exp */ for( exp=0, i=8, exp_tmp=1; i>0; i--){ if( buf[i] == '1') { exp += exp_tmp; } exp_tmp*=2; } /* get fraction */ for(i=9, real=(double)0, frag_tmp = (double) 1/2; i< len; i++) { if( buf[i] == '1') { real += frag_tmp; } frag_tmp /= (double) 2; } while(exp>0) { real *= 2; exp--; } real *= (double) sign; return real; } int ieee754_64(char *data, double real) { int exp=0, i=0, exp_tmp; double cal, frag_tmp; static char buf[64]; bzero(buf, sizeof(buf)); cal = real; /* get sign */ if( cal < 0 ){ cal *= (double) -1; buf[0] = 1; } else { buf[0] = 0; } /* get exp */ while( cal >= 1.0 ) { cal /= 2; exp++; } for( i=11, exp_tmp=1; i>0; i--){ if( (exp & exp_tmp) ) { buf[i] = 1; } else { buf[i] = 0; } exp_tmp *=2 ; } /* get fraction */ for(i=12, frag_tmp = (double) 1/2; i< 64; i++) { if( (cal - frag_tmp) >= 0 ){ buf[i] = 1; cal = (double) cal - (double) frag_tmp; } else { buf[i] = 0; } frag_tmp /= (double) 2; } /* To ascii */ for(i=0; i<64; i++) { buf[i] += '0'; } strncpy(data, buf, 64); return 0; } double rev_ieee754_64(char *buf) { int exp=0, i=0, exp_tmp, sign; double real, frag_tmp; int len=64; /* get sign */ if( buf[0] == '1' ){ sign = -1; } else { sign = 1; } /* get exp */ for( exp=0, i=11, exp_tmp=1; i>0; i--){ if( buf[i] == '1') { exp += exp_tmp; } exp_tmp*=2; } /* get fraction */ for(i=12, real=(double)0, frag_tmp = (double) 1/2; i< len; i++) { if( buf[i] == '1') { real += frag_tmp; } frag_tmp /= (double) 2; } while(exp>0) { real *= 2; exp--; } real *= (double) sign; return real; } /* test */ int main(void) { int i, j; char buf[32], buf2[64]; for(i=1; i<=1000000; i*=2) { bzero(buf, sizeof(buf)); bzero(buf2, sizeof(buf2)); ieee754( (char*)buf, (double) i); printf("[32bit] %20f ->\t", rev_ieee754( (char*)buf));; for(j=0; j<sizeof(buf); j++) { printf("%c ", buf[j]); } printf("\n"); ieee754_64( buf2, (double) i); printf("[64bit] %20f ->\t", rev_ieee754_64( (char*)buf2));; for(j=0; j<sizeof(buf2);j++) { printf("%c ", buf2[j]); } printf("\n"); } return 0; } |
沒有留言:
張貼留言
歡迎留言