為什麼說有的浮點數無法精確的表示

2021-03-09 21:04:23 字數 7442 閱讀 8515

1樓:徐天來

比如儲存10進位制0.1,為什麼無法保證每一臺機子對其儲存的值不一樣呢?

0.10.2 0 0.2

0.4 0 0.4

0.8 0 0.8

1.6 1 0.6

1.2 1 0.2

0.4 0 0.4

0.8 0 0.8

1.6 1 0.6

1.2 1 0.2

二進位制:

0.0001 1001 1001 1001 .... 1001

1.1001 1001 1001...1001*2^-4

符號位:0

階碼:-4+127=123 0111 1011

0011 1101 1100 1100 1100 1100 1100 1101

3 d c c c c c c

即:0x3d cc cc cc

每一臺機子裡的值都是0x3d cc cc cc

不都一樣嗎?

不是嗎浮點數結構,可以看ieee754

我已經按照這個標準手工求解出結果來了

float val=0.1f;

printf("0x%x",val);

return 0;

0xa0000000請按任意鍵繼續. . .

的結果和記憶體中觀察的結果不一致啊

1.1 - 1.0 和 2.1 - 2.0 是否一致,然後3.1,4.1等等?浮點數是要用來計算的。

float給push到printf的堆疊的時候會轉成double……你看到的是(double)0.1的高32位或者低32位……

趙老師說過,十進位制小數無法精確表示 三分之一,

同理,二進位制小數也無法精確表示 十分之一。

用10進位制小數不能精確表示某些三進位制小數0.1(3)=0.33333333333……(10)

同理,用二進位制小數也不能精確表示某些10進位制小數。

按照這個說法,printf列印float浮點數 的十六進位制, 豈不是很危險,結果顯示是錯誤的,因為已經被push了

double了.

還有printf一個doulbe的十六進位制也是錯誤的, 只有低4個位元組可以列印。

如何解決呢?

spritnf也解決不了列印一個浮點數的十六進位制

比如儲存10進位制0.1,為什麼無法保證每一臺機子對其儲存的值不一樣呢?

如果說每臺機器存貯浮點數的格式都是iee754,這個說法顯然是錯的,必然是一樣的

那為什麼 6樓,7樓,說無法精確的表示, 而且這種答案,很多帖子裡都複製貼上過去。

計算機裡的數字都一樣,他們想什麼呢

無法精確表示和不同機器值不一樣不是一回事,很多數的確是無法精確表示,你可以自己查一下iee754格式

printf看到%f也是當做double列印的。也就是說printf不區分%f和%lf。scanf是區分的。

>按照這個說法,printf列印float浮點數 的十六進位制, 豈不是很危險,結果顯示是錯誤的,因為已經被push了

double了

2樓:坑貨的悲哀

因為二進位制只能表bai示2的n次方的數du,n可以取zhi負值,3.3無法dao用2的n次方的陣列合計算回出來,所以無法精確表示答:3.

3=1*2+1*1+0*1/2+1*1/4+0*1/8+0*1/16+1*1/32+...

其中分式的分母只能是2的倍數(二進位制所限),3.3的二進位制表示是11.01001.....

有些數比如1/3就無法精確計算,只能無限逼近

二進位制中浮點數怎麼表示

3樓:匿名使用者

二進位制中浮點數浮點表示例子:

浮點二進位制數是:1011 1101 0100 0000 0000 0000 0000 0000

按1,8,23位分成三段:

1 01111010 10000000000000000000000最後一段是尾數。前面加上"1", 就是 1.10000000000000000000000

下面確定小數點位置。階碼是01111010,加上00000101才是01111111(127),所以他減去127的偏移量得-5。

要注意其他機器的浮點數表示方法可能不同.,不能任意移植。

4樓:匿名使用者

目前c/c++編譯器標準都遵照ieee制定的浮點數表示法來進行float,double運算。這種結構是一種科學計數法,用符號、指數和尾數來表示,底數定為2——即把一個浮點數表示為尾數乘以2的指數次方再添上符號。下面是具體的規格:

符號位 階碼 尾數 長度

float 1 8 23 32

double 1 11 52 64 以下通過幾個例子講解浮點數如何轉換為二進位制數例一:已知:double型別38414.

4。求:其對應的二進位制表示。

分析:double型別共計64位,摺合8位元組。由最高到最低位分別是第63、62、61、……、0位:

最高位63位是符號位,1表示該數為負,0表示該數為正;

62-52位,一共11位是指數位;

51-0位,一共52位是尾數位。

步驟:按照ieee浮點數表示法,下面先把38414.4轉換為十六進位制數。

把整數部和小數部分開處理:整數部直接化十六進位制:960e。小數的處理:

0.4=0.5*0+0.25*1+0.125*1+0.0625*0+……

實際上這永遠算不完!這就是著名的浮點數精度問題。所以直到加上前面的整數部分算夠53位就行了。隱藏位技術:最高位的1不寫入記憶體(最終保留下來的還是52位)。

如果你夠耐心,手工算到53位那麼因該是:38414.4(10)=1001011000001110.

0110011001100110011001100110011001100(2)科學記數法為:1.001011000001110 0110011001100110011001100110011001100,右移了15位,所以指數為15。

或者可以如下理解:1.001011000001110 0110011001100110011001100110011001100×2^15

於是來看階碼,按ieee標準一共11位,可以表示範圍是-1024 ~ 1023。因為指數可以為負,為了便於計算,規定都先加上1023(2^10-1),在這裡,階碼:15+1023=1038。

二進位制表示為:100 00001110;

符號位:因為38414.4為正對應 為0;

合在一起(注:尾數二進位制最高位的1不要):

01000000 11100010 11000001 110 01100 11001100 11001100 11001100 11001100 例二:已知:整數3490593(16進製表示為0x354321)。

求:其對應的浮點數3490593.0的二進位制表示。

解法如下:先求出整數3490593的二進位制表示: h:

3 5 4 3 2 1 (十六進位制表示) b: 0011 0101 0100 0011 0010 0001 (二進位制表示) │←──────21─────→│ 即: 1.

1010101000011001000012×221可見,從左算起第一個1後有21位,我們將這21為作為浮點數的小數表示,單精度浮點數float由符號位1位,指數域位k=8位,小數域位(尾數)n=23位構成,因此對上面得到的21位小數位我們還需要補上2個0,得到浮點數的小數域表示為: 1 0101 0100 0011 0010 0001 00 float型別的偏置量bias=2k-1-1=28-1-1=127,但還要補上剛才因為右移作為小數部分的21位,因此偏置量為127+21=148,就是ieee浮點數表示標準: v = (-1)s×m×2e e = e-bias中的e,此前計算bias=127,剛好驗證了e=148-127=21。

將148轉為二進位制表示為10010100,加上符號位0,最後得到二進位制浮點數表示1001010010101010000110010000100,其16進製表示為: h: 4 a 5 5 0 c 8 4 b:

0100 1010 0101 0101 0000 1100 1000 0100 |←──── 21 ─────→ | 1|←─8 ─→||←───── 23 ─────→ | 這就是浮點數3490593.0(0x4a550c84)的二進位制表示。 例三:

0.5的二進位制形式是0.1它用浮點數的形式寫出來是如下格式 0 01111110 00000000000000000000000

符號位 階碼 小數位正數符號位為0,負數符號位為1階碼是以2為底的指數小數位表示小數點後面的數字

下面我們來分析一下0.5是如何寫成0 01111110 00000000000000000000000

首先0.5是正數所以符號位為0再來看階碼部分,0.5的二進位制數是0.

1,而0.1是1.0*2^(-1),所以我們總結出來:

要把二進位制數變成(1.f)*2^(exponent)的形式,其中exponent是指數而由於階碼有正負之分所以階碼=127+exponent;即階碼=127+(-1)=126 即 01111110餘下的小數位為二進位制小數點後面的數字,即00000000000000000000000

由以上分析得0.5的浮點數儲存形式為0 01111110 00000000000000000000000 注:如果只有小數部分,那麼需要右移小數點.

比如右移3位才能放到第一個1的後面, 階碼就是127-3=124.例四 (20.59375)10 =(10100.

10011 )2

首先分別將整數和分數部分轉換成二進位制數:

20.59375=10100.10011

然後移動小數點,使其在第1,2位之間

10100.10011=1.010010011×2^4 即e=4

於是得到:

s=0, e=4+127=131, m=010010011

最後得到32位浮點數的二進位制儲存格式為:

0100 1001 1010 0100 1100 0000 0000 0000=(41a4c000)16 例五:

-12.5轉為單精度二進位制表示

12.5:

1. 整數部分12,二進位制為1100; 小數部分0.5, 二進位制是.1,先把他們連起來,從第一個1數起取24位(後面補0):

1100.10000000000000000000

這部分是有效數字。(把小數點前後兩部分連起來再取掉頭前的1,就是尾數)

2. 把小數點移到第一個1的後面,需要左移3位(1.10010000000000000000000*2^3), 加上偏移量127:

127+3=130,二進位制是10000010,這是階碼。

3. -12.5是負數,所以符號位是1。把符號位,階碼和尾數連起來。注意,尾數的第一位總是1,所以規定不存這一位的1,只取後23位:

1 10000010 10010000000000000000000

把這32位按8位一節整理一下,得:

11000001 01001000 00000000 00000000

就是十六進位制的 c1480000.

例六:2.025675

1. 整數部分2,二進位制為10; 小數部分0.025675, 二進位制是.0000011010010010101001,先把他們連起來,從第一個1數起取24位(後面補0):

10.0000011010010010101001

這部分是有效數字。把小數點前後兩部分連起來再取掉頭前的1,就是尾數: 00000011010010010101001

2. 把小數點移到第一個1的後面,左移了1位, 加上偏移量127:127+1=128,二進位制是10000000,這是階碼。

3. 2.025675是正數,所以符號位是0。把符號位,階碼和尾數連起來:

0 10000000 00000011010010010101001

把這32位按8位一節整理一下,得:

01000000 00000001 10100100 10101001

就是十六進位制的 4001a4a9.

例七:(逆向求十進位制整數)一個浮點二進位制數手工轉換成十進位制數的例子:

假設浮點二進位制數是 1011 1101 0100 0000 0000 0000 0000 0000

按1,8,23位分成三段:

1 01111010 10000000000000000000000

最後一段是尾數。前面加上"1.", 就是 1.10000000000000000000000

下面確定小數點位置。由e = e-bias,階碼e是01111010,加上00000101才是01111111(127),

所以他減去127的偏移量得e=-5。(或者化成十進位制得122,122-127=-5)。

因此尾數1.10(後面的0不寫了)是小數點右移5位的結果。要復原它就要左移5位小數點,得0.0000110, 即十進位制的0.046875 。

最後是符號:1代表負數,所以最後的結果是 -0.046875 。

注意:其他機器的浮點數表示方法可能與此不同. 不能任意移植。

再看一例(類似例七):比如:53004d3e二進位制表示為:

01010011000000000100110100111110按照1個符號 8個指數 23個小數位劃分0 10100110 00000000100110100111110正確的結果轉出來應該是551051722752.0該怎麼算?好,我們根據ieee的浮點數表示規則劃分,得到這個浮點數的小數位是:

00000000100110100111110

那麼它的二進位制表示就應該是:

1.000000001001101001111102 × 239

這是怎麼來的呢? 別急,聽我慢慢道來。

標準化公式中的m要求在規格化的情況下,取值範圍116610

即e=166,由此算出e=e-bias=166-127=39,就是說將整數二進位制表示轉為標準的浮點數二進位制表示的時候需要將小數點左移39位,好,我們現在把它還原得到整數的二進位制表示:1 00000000100110100111110 00000000000000001│←───── 23─────→│←─── 16───→│

23+16=39,後面接著就是小數點了。

拿出計算器,輸入二進位制數1000000001001101001111100000000000000000

轉為十進位制數,不正是:551051722752麼!

通過這例六例七,介紹了將整數二進位制表示轉浮點數二進位制表示的逆過程,還是希望大家不但能掌握轉化的方法,更要理解轉化的基本原理。

單精度浮點數的精度為什麼是7位,單精度的浮點數有效數字為什麼是七位

這個比較複雜,建議你找一下ieee754標準看一下。這個簡單說一下吧 在ieee754標準中進行了單精度浮點數 float 和雙精度數浮點數 double 的定義。float有32bit,double有64bit。它們的構成包括符號位 指數位和尾數位。這些位的構成如下 float 第31位 佔1bi...

浮點數所能表示的數值範圍和精度撒於什麼

浮點數所能表示的數值範圍和精度取決於階碼和尾數。階碼 採用指數的實際值加上固定的偏移值的辦法表示浮點數的指數,好處是可以用長度為 個位元的無符號整數來表示所有的指數取值,這使得兩個浮點數的指數大小的比較更為容易,實際上可以按照字典序比較兩個浮點表示的大小。這種移碼錶示的指數部分,中文稱作階碼。定點數...

為什麼機械錶的價值高為什麼有的手錶這麼貴

不可否認很多機械錶是存在 營銷溢價的,但是如果你見過瑞士機械錶的單個零件,你會感嘆這些在1mm以下的尺度加工出各種形狀 曲面的精密零件。然後再將它們組裝在一起又是需要長時間積累經驗的。無論是加工還是組裝,你都幾乎不可能在全世界找到合格又便宜的人工。我覺得用的久一點,男人喜歡齒輪一類的東西,女人喜歡珠...