IEEE754标准 单精度(32位)/双精度(64位)浮点数直接解码 ,不借助任何的其他库函数,
采用 ascStrAdd() 对ASCII表示的数字串进行计算得到)内存中的浮点数位串的的10进制的数值
///
单精度(32位)浮点数的结构:
名称 长度 比特位置
符号位 Sign (S) : 1bit (b31)
指数部分Exponent (E) : 8bit (b30-b23)
尾数部分Mantissa (M) : 23bit (b22-b0)
其中的指数部分(E)采用的偏置码(biased)的形式来表示正负指数,若E<127则为负的指数,否则为非负的指数。
另外尾数部分M存储的是当把一个浮点数规范化表示后的1.zozooz...(二进制的)形式的zozooz的部分的比特串,共23位.
求值方法: (-1)^S*(1.M)*2^(E-127)
///
双精度(64位)浮点数的结构与单精度相仿
名称 长度 比特位置
符号位 Sign (S) : 1bit (b63)
指数部分Exponent (E) : 11bit (b62-b52)
尾数部分Mantissa (M) : 52bit (b51-b0)
双精度的指数部分(E)采用的偏置码为1023
求值方法:(-1)^S*(1.M)*2^(E-1023)
/
单精度(32位)浮点数的解码程序,忽略处理inf,NaN,0等形式的浮点数。
/*
* floatdis32.c
* dissection for IEEE754 floating-point number (32 bit)
* structure: Sign : 1bit
* Exponent: 8bit
* Mantissa: 23bit
* algorithm: (-1)^S*(1.M)*2^(E-127)
*
* Time-stamp: <2012-07-30 09:58:15 root>
* snallie@tom.com
*
* make: gcc f.c -o f -lm
*
*/
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#define LEN 32
#define BIAS_EXPONENT 127
void ascStrAdd(char *a, char *b, char *sum);
void asciiNumAdd_aDecimal(char a, char b, char *sum, char *Hcarry,
char Lcarry);
char fltable[][33] = {
"00000000000000000000000000000000", /* Zero */
"50000000000000000000000000000000", /* 2^-1 */
"25000000000000000000000000000000", /* 2^-2 */
"12500000000000000000000000000000", /* 2^-3 */
"06250000000000000000000000000000", /* 2^-4 */
"03125000000000000000000000000000", /* 2^-5 */
"01562500000000000000000000000000", /* 2^-6 */
"00781250000000000000000000000000", /* 2^-7 */
"00390625000000000000000000000000", /* 2^-8 */
"00195312500000000000000000000000", /* 2^-9 */
"00097656250000000000000000000000", /* 2^-10 */
"00048828125000000000000000000000", /* 2^-11 */
"00024414062500000000000000000000", /* 2^-12 */
"00012207031250000000000000000000", /* 2^-13 */
"00006103515625000000000000000000", /* 2^-14 */
"00003051757812500000000000000000", /* 2^-15 */
"00001525878906250000000000000000", /* 2^-16 */
"00000762939453125000000000000000", /* 2^-17 */
"00000381469726562500000000000000", /* 2^-18 */
"00000190734863281250000000000000", /* 2^-19 */
"00000095367431640625000000000000", /* 2^-20 */
"00000047683715820312500000000000", /* 2^-21 */
"00000023841857910156250000000000", /* 2^-22 */
"00000011920928955078125000000000", /* 2^-23 */
"00000005960464477539062500000000", /* 2^-24 */
"00000002980232238769531250000000", /* 2^-25 */
"00000001490116119384765625000000", /* 2^-26 */
"00000000745058059692382812500000", /* 2^-27 */
"00000000372529029846191406250000", /* 2^-28 */
"00000000186264514923095703125000", /* 2^-29 */
"00000000093132257461547851562500", /* 2^-30 */
"00000000046566128730773925781250", /* 2^-31 */
"00000000023283064365386962890625", /* 2^-32 */
};
int main(int argc, char **argv)
{
/*
char:1 short:2 int:4 long:4 float:4 double:8
*/
char buf[33];
buf[32] = 0;
float f = 100.8912345600108992; //3.40E38; //100.89001089925383;
char *p = (char *) (&f);
unsigned int *pi = (int *) (&f);
unsigned int k;
int i = 0;
if (argc > 1) {
f = atof(argv[1]);
}
printf
("<<<< IEEE 754 single precision float-point numeral (32bit) dissection >>>>\n");
k = *pi;
printf("float number to be dissected: f = %-32.32g\n", f);
for (i = 3, printf("Hex dump: "); i >= 0; i--)
printf("%02X ", p[i] & 0xff);
printf("\n");
for (i = 31, printf("Binary dump: "); i >= 0; i--) {
buf[i] = (char) (k % 2 + 0x30);
k >>= 1;
}
for (i = 0; i < 32; i++) {
printf("%c%s", buf[i], (i + 1) % 4 == 0 ? " " : "");
}
for (i = 0; i < 32; i++) {
if (i == 0)
printf("\nsign : %c \nexponent: ", buf[i]);
if (i > 0 && i <= 8)
printf("%c", buf[i]);
if (i == 8)
printf("\nmantissa: ");
if (i > 8)
printf("%c", buf[i]);
}
printf("\n");
{ // dissection
int i;
float tmpflt;
char mantissa[33] = "00000000000000000000000000000000";
char tmpMant[36];
int exponent = 0;
mantissa[32] = '\0';
char *buf2 = buf + 9;
for (i = 0; i < 23; i++) // compute mantissa to decimal
{
if (buf2[i] != '0') {
ascStrAdd(mantissa, fltable[i + 1], mantissa);
printf("%s\n", mantissa);
}
}
mantissa[32] = '\0';
for (i = 1; i < 9; i++) // compute exponent to integer
{
if (buf[i] != '0') {
exponent += pow(2, 8 - i);
}
}
exponent -= BIAS_EXPONENT;
printf("Integer exponent:##%d\n", exponent);
printf("result:\t\t %c1.%sE2^%d\n", buf[0]==0x31?'-':' ',mantissa, exponent);
// transform the binary format to float , stored in tmpflt
tmpMant[1] = '.';
tmpMant[0] = '0';
strcpy(tmpMant + 2, mantissa);
tmpflt = atof(tmpMant) + 1;
printf("Decimal equivalent: %c%-64.64g\n",buf[0]==0x31?'-':' ',
tmpflt * pow(2, exponent));
}
return 0;
}
void ascStrAdd(char *a, char *b, char *sum)
{
int i;
char Lcarry = 0x30;
// char Hcarry = 0x30;
for (i = 31; i >= 0; i--) {
asciiNumAdd_aDecimal(a[i], b[i], &sum[i], &Lcarry, Lcarry);
}
}
void asciiNumAdd_aDecimal(char a, char b, char *sum, char *Hcarry,
char Lcarry)
{
int ta = a - 0x30;
int tb = b - 0x30;
int tLc = Lcarry - '0';
*sum = (ta + tb + tLc) % 10 + 0x30;
if (ta + tb > 9 || ta + tLc > 9 || tb + tLc > 9 || ta + tb + tLc > 9) {
*Hcarry = 0x31; //1
} else {
*Hcarry = 0x30; //0
}
}
/
双精度(64位)浮点数的解码程序,忽略处理inf,NaN,0等形式的浮点数。
/** floatdis64.c
* dissection for IEEE754 double float (64 bit)
* structure: Sign : 1bit
* Exponent: 11bit
* Mantissa: 52bit
* algorithm: (-1)^S*(1.M)*2^(E-1023)
*
* Time-stamp: <2012-07-30 09:57:24 root>
* Thu Jul 3 10:41:44 HKT 2008
* snallie@tom.com
*
* make: gcc f.c -o f -lm
*
*/
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#define LEN 64
#define BIAS_EXPONENT 1023
void ascStrAdd(char *a, char *b, char *sum);
void asciiNumAdd_aDecimal(char a, char b, char *sum, char *Hcarry,
char Lcarry);
char fltable[][65] = {
"0000000000000000000000000000000000000000000000000000000000000000", /* (Zero) */
"5000000000000000000000000000000000000000000000000000000000000000", /* (2^-1) */
"2500000000000000000000000000000000000000000000000000000000000000", /* (2^-2) */
"1250000000000000000000000000000000000000000000000000000000000000", /* (2^-3) */
"0625000000000000000000000000000000000000000000000000000000000000", /* (2^-4) */
"0312500000000000000000000000000000000000000000000000000000000000", /* (2^-5) */
"0156250000000000000000000000000000000000000000000000000000000000", /* (2^-6) */
"0078125000000000000000000000000000000000000000000000000000000000", /* (2^-7) */
"0039062500000000000000000000000000000000000000000000000000000000", /* (2^-8) */
"0019531250000000000000000000000000000000000000000000000000000000", /* (2^-9) */
"0009765625000000000000000000000000000000000000000000000000000000", /* (2^-10) */
"0004882812500000000000000000000000000000000000000000000000000000", /* (2^-11) */
"0002441406250000000000000000000000000000000000000000000000000000", /* (2^-12) */
"0001220703125000000000000000000000000000000000000000000000000000", /* (2^-13) */
"0000610351562500000000000000000000000000000000000000000000000000", /* (2^-14) */
"0000305175781250000000000000000000000000000000000000000000000000", /* (2^-15) */
"0000152587890625000000000000000000000000000000000000000000000000", /* (2^-16) */
"0000076293945312500000000000000000000000000000000000000000000000", /* (2^-17) */
"0000038146972656250000000000000000000000000000000000000000000000", /* (2^-18) */
"0000019073486328125000000000000000000000000000000000000000000000", /* (2^-19) */
"0000009536743164062500000000000000000000000000000000000000000000", /* (2^-20) */
"0000004768371582031250000000000000000000000000000000000000000000", /* (2^-21) */
"0000002384185791015625000000000000000000000000000000000000000000", /* (2^-22) */
"0000001192092895507812500000000000000000000000000000000000000000", /* (2^-23) */
"0000000596046447753906250000000000000000000000000000000000000000", /* (2^-24) */
"0000000298023223876953125000000000000000000000000000000000000000", /* (2^-25) */
"0000000149011611938476562500000000000000000000000000000000000000", /* (2^-26) */
"0000000074505805969238281250000000000000000000000000000000000000", /* (2^-27) */
"0000000037252902984619140625000000000000000000000000000000000000", /* (2^-28) */
"0000000018626451492309570312500000000000000000000000000000000000", /* (2^-29) */
"0000000009313225746154785156250000000000000000000000000000000000", /* (2^-30) */
"0000000004656612873077392578125000000000000000000000000000000000", /* (2^-31) */
"0000000002328306436538696289062500000000000000000000000000000000", /* (2^-32) */
"0000000001164153218269348144531250000000000000000000000000000000", /* (2^-33) */
"0000000000582076609134674072265625000000000000000000000000000000", /* (2^-34) */
"0000000000291038304567337036132812500000000000000000000000000000", /* (2^-35) */
"0000000000145519152283668518066406250000000000000000000000000000", /* (2^-36) */
"0000000000072759576141834259033203125000000000000000000000000000", /* (2^-37) */
"0000000000036379788070917129516601562500000000000000000000000000", /* (2^-38) */
"0000000000018189894035458564758300781250000000000000000000000000", /* (2^-39) */
"0000000000009094947017729282379150390625000000000000000000000000", /* (2^-40) */
"0000000000004547473508864641189575195312500000000000000000000000", /* (2^-41) */
"0000000000002273736754432320594787597656250000000000000000000000", /* (2^-42) */
"0000000000001136868377216160297393798828125000000000000000000000", /* (2^-43) */
"0000000000000568434188608080148696899414062500000000000000000000", /* (2^-44) */
"0000000000000284217094304040074348449707031250000000000000000000", /* (2^-45) */
"0000000000000142108547152020037174224853515625000000000000000000", /* (2^-46) */
"0000000000000071054273576010018587112426757812500000000000000000", /* (2^-47) */
"0000000000000035527136788005009293556213378906250000000000000000", /* (2^-48) */
"0000000000000017763568394002504646778106689453125000000000000000", /* (2^-49) */
"0000000000000008881784197001252323389053344726562500000000000000", /* (2^-50) */
"0000000000000004440892098500626161694526672363281250000000000000", /* (2^-51) */
"0000000000000002220446049250313080847263336181640625000000000000", /* (2^-52) */
};
int main(int argc, char **argv)
{
/*
char:1 short:2 int:4 long:4 long long:8 float:4 double:8
*/
char buf[65];
buf[64] = 0;
double f = 100.8912345600108992; //3.40E38; //100.89001089925383;
char *p = (char *) (&f);
unsigned long long *pi = (unsigned long long *) (&f);
unsigned long long k;
int i = 0;
if (argc > 1) {
f = atof(argv[1]);
}
printf
("<<<< IEEE 754 single precision float-point number (64bit) dissection >>>>\n");
k = *pi;
printf("float numeral to be dissected: f = %-64.64g\n", f);
for (i = 7, printf("Hex dump: "); i >= 0; i--)
printf("%02X ", p[i] & 0xff);
printf("\n");
for (i = 63, printf("Binary dump: "); i >= 0; i--) {
buf[i] = (char) (k % 2 + 0x30);
k >>= 1;
}
for (i = 0; i < 64; i++) {
printf("%c%s", buf[i], (i + 1) % 4 == 0 ? " " : "");
}
for (i = 0; i < 64; i++) {
if (i == 0)
printf("\nsign : %c \nexponent: ", buf[i]);
if (i > 0 && i <= 11)
printf("%c", buf[i]);
if (i == 11)
printf("\nmantissa: ");
if (i > 11)
printf("%c", buf[i]);
}
printf("\n");
{ // dissection
int i;
double tmpflt;
char mantissa[65] = "0000000000000000000000000000000000000000000000000000000000000000"; /* (Zero) */
char tmpMant[68];
int exponent = 0;
mantissa[64] = '\0';
char *buf2 = buf + 12;
for (i = 0; i < 52; i++) // compute mantissa to decimal
{
if (buf2[i] != '0') {
ascStrAdd(mantissa, fltable[i + 1], mantissa);
printf("%s\n", mantissa);
}
}
mantissa[64] = '\0';
for (i = 1; i < 12; i++) // compute exponent to integer
{
if (buf[i] != '0') {
exponent += pow(2, 11 - i);
}
}
exponent -= BIAS_EXPONENT;
printf("Integer exponent:##%d\n", exponent);
printf("result:\t\t %c1.%sE2^%d\n", buf[0]==0x31?'-':' ',mantissa, exponent);
// transform the binary format to float , stored in tmpflt
tmpMant[1] = '.';
tmpMant[0] = '0';
strcpy(tmpMant + 2, mantissa);
tmpflt = atof(tmpMant) + 1;
printf("Decimal equivalent: %c%-64.64g\n",buf[0]==0x31?'-':' ',
tmpflt * pow(2, exponent));
}
return 0;
}
void ascStrAdd(char *a, char *b, char *sum)
{
int i;
char Lcarry = 0x30;
// char Hcarry = 0x30;
for (i = 63; i >= 0; i--) {
asciiNumAdd_aDecimal(a[i], b[i], &sum[i], &Lcarry, Lcarry);
}
}
void asciiNumAdd_aDecimal(char a, char b, char *sum, char *Hcarry,
char Lcarry)
{
int ta = a - 0x30;
int tb = b - 0x30;
int tLc = Lcarry - '0';
*sum = (ta + tb + tLc) % 10 + 0x30;
if (ta + tb > 9 || ta + tLc > 9 || tb + tLc > 9 || ta + tb + tLc > 9) {
*Hcarry = 0x31; //1
} else {
*Hcarry = 0x30; //0
}
}
/*
{
float f;
char *str="1234.67";
f=atof(str);
printf("string=%s, float=%f\n",str,f);
return 0;
}
*/
/* verify the function of asciiNumAdd_aDecimal
{
char a = '0', b = '0', Lc = '0';
char sum = 0x30, Hc = 0x3;
int i = 0;
for (Lc = '0'; Lc <= '1'; Lc++)
for (a = '0'; a <= '9'; a++)
for (b = '0'; b <= '9'; b++) {
asciiNumAdd_aDecimal(a, b, &sum, &Hc, Lc);
printf("%03d: %c+%c+%c=%c:%c\n", i++, a, b, Lc, Hc,
sum);
}
}
*/
/* verify the function of ascStrAdd
{
int i,j;
for(i=1;i<33;i++)
for(j=i+1;j<33;j++)
{
printf("0.%s + 0.%s = ",fltable[i],fltable[j]);
ascStrAdd(fltable[i],fltable[j],fltable[0]);
fltable[0][32]='\0';
printf("0.%s\n",fltable[0]);
strcpy(fltable[0],"00000000000000000000000000000000");
}
}
*/
单精度(32位)浮点数 程序运行实例
[root@jocks cs]# ./fl32 -0.0000323E-10
<<<< IEEE 754 single precision float-point numeral (32bit) dissection >>>>
float number to be dissected: f = -3.2300000551272432802729639433892e-15
Hex dump: A7 68 BE FC
Binary dump: 1010 0111 0110 1000 1011 1110 1111 1100
sign : 1
exponent: 01001110
mantissa: 11010001011111011111100
50000000000000000000000000000000
75000000000000000000000000000000
81250000000000000000000000000000
81640625000000000000000000000000
81738281250000000000000000000000
81787109375000000000000000000000
81811523437500000000000000000000
81823730468750000000000000000000
81829833984375000000000000000000
81831359863281250000000000000000
81832122802734375000000000000000
81832504272460937500000000000000
81832695007324218750000000000000
81832790374755859375000000000000
81832838058471679687500000000000
Integer exponent:##-49
result: -1.81832838058471679687500000000000E2^-49
Decimal equivalent: -3.2300000551272432802729639433891861699521541595458984375e-15
[root@jocks cs]#
//
双精度(64位)浮点数 程序运行实例
[root@jocks cs]# ./fl64 -3.14159E-10
<<<< IEEE 754 single precision float-point number (64bit) dissection >>>>
float numeral to be dissected: f = -3.141590000000000211787042998036511079473775964743254007771611214e-10
Hex dump: BD F5 96 BE 5A F7 3D 85
Binary dump: 1011 1101 1111 0101 1001 0110 1011 1110 0101 1010 1111 0111 0011 1101 1000 0101
sign : 1
exponent: 01111011111
mantissa: 0101100101101011111001011010111101110011110110000101
2500000000000000000000000000000000000000000000000000000000000000
3125000000000000000000000000000000000000000000000000000000000000
3437500000000000000000000000000000000000000000000000000000000000
3476562500000000000000000000000000000000000000000000000000000000
3486328125000000000000000000000000000000000000000000000000000000
3491210937500000000000000000000000000000000000000000000000000000
3492431640625000000000000000000000000000000000000000000000000000
3492736816406250000000000000000000000000000000000000000000000000
3492889404296875000000000000000000000000000000000000000000000000
3492965698242187500000000000000000000000000000000000000000000000
3493003845214843750000000000000000000000000000000000000000000000
3493022918701171875000000000000000000000000000000000000000000000
3493025302886962890625000000000000000000000000000000000000000000
3493025898933410644531250000000000000000000000000000000000000000
3493026196956634521484375000000000000000000000000000000000000000
3493026271462440490722656250000000000000000000000000000000000000
3493026290088891983032226562500000000000000000000000000000000000
3493026299402117729187011718750000000000000000000000000000000000
3493026304058730602264404296875000000000000000000000000000000000
3493026306387037038803100585937500000000000000000000000000000000
3493026306969113647937774658203125000000000000000000000000000000
3493026307260151952505111694335937500000000000000000000000000000
3493026307405671104788780212402343750000000000000000000000000000
3493026307423860998824238777160644531250000000000000000000000000
3493026307432955945841968059539794921875000000000000000000000000
3493026307437503419350832700729370117187500000000000000000000000
3493026307439777156105265021324157714843750000000000000000000000
3493026307440345590293873101472854614257812500000000000000000000
3493026307440629807388177141547203063964843750000000000000000000
3493026307440638689172374142799526453018188476562500000000000000
3493026307440640909618423393112607300281524658203125000000000000
Integer exponent:##-32
result: -1.3493026307440640909618423393112607300281524658203125000000000000E2^-32
Decimal equivalent: -3.141590000000000211787042998036511079473775964743254007771611214e-10
[root@jocks cs]#