IEEE754标准 单精度(32位)/双精度(64位)浮点数解码

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]#










  • 7
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值