歡迎您光臨本站 註冊首頁

C語言,分析浮點數存儲格式

←手機掃碼閱讀     火星人 @ 2014-03-12 , reply:0
  
問題源於printf函數的%x格式,無法反映浮點數在內存中的二進位存儲

下面用C的聯合體和位段,分析浮點數在內存中的二進位存儲格式,純屬好奇,當作練習:)

首先,收集浮點數的相關知識

維基百科,閱讀以下兩篇文章

Location: http://zh.wikipedia.org/wiki/%E6%B5%AE%E7%82%B9%E6%95%B0            
浮點數

Location: http://zh.wikipedia.org/wiki/IEEE_754                               
IEEE 754

獲知單精度32位浮點數的格式,如下



參考以上資料,使用C語言的聯合體和位段,編寫程序,運行如下

$ cat main.c
#include <stdio.h>

union {
  float a;
  unsigned int b;
} ex;

struct float_32_format {
  unsigned int fraction: 23;    /* 有效數位 */
  unsigned int exp: 8;        /* 指數位 */
  unsigned int sign: 1;        /* 符號位 */
};                /* 倒序表示 */

void analysis(float val)
{
  struct float_32_format *format;

  printf("--- 開始分析浮點數 %f\n",val);

  ex.a=val;
  printf("-- 單精度浮點數存儲的4個位元組,10進位表示: %u\n",ex.b);
  printf("-- 單精度浮點數存儲的4個位元組,16進位表示: 0x%X\n",ex.b); /* 妙用union */

  format=(struct float_32_format*)(&ex.a); /* ex.a或ex.b皆可 */
  printf("-- sign: %u\n",format->sign);
  printf("-- exp: %u\n",format->exp);
  printf("-- fraction: %u ( 0x%X )\n",format->fraction,format->fraction);
 
  printf("\n");
}

int main()
{
  printf("'float' size: %d\n",sizeof(float));
  printf("'unsigned int' size: %d\n\n",sizeof(unsigned int));

  analysis(-20.25);

  return 0;
}
$ cat Makefile
all:
    gcc main.c

clean:
    rm -f a.out *~
$ ls
main.c  Makefile
$ make
gcc main.c
$ ./a.out
'float' size: 4
'unsigned int' size: 4

--- 開始分析浮點數 -20.250000
-- 單精度浮點數存儲的4個位元組,10進位表示: 3248619520
-- 單精度浮點數存儲的4個位元組,16進位表示: 0xC1A20000
-- sign: 1
-- exp: 131
-- fraction: 2228224 ( 0x220000 )

$

分析程序輸出的數據

sign=1, 為負數
exp=131, 131-127=4
fraction=0x220000, 二進位表示: 010 0010 0000 0000 0000 0000 (23位)

整合起來:

- 1.010 0010 0000 0000 0000 0000 x 2^4
- 1010 0.010 0000 0000 0000 0000

符號部分 負數
整數部分 10100 = 1x2^4 + 1x2^2 = 16+4 = 20
小數部分 0.010 = 1x2^-2 = 0.25

綜上所述,單精度浮點數存儲的4個位元組,16進位表示0xC1A20000,即為浮點數-20.25

Q.E.D.

讀<<C和指針>>,新年回家複習C語言,準備找工作了

C


[火星人 ] C語言,分析浮點數存儲格式已經有557次圍觀

http://coctec.com/docs/program/show-post-71615.html