3 float py 位小数 裁剪_对一个 float 精度问题的分析
原問題見:
有1個c語音的源代碼不清楚它為什么輸出這個數,所以想請教一下??www.zhihu.com大概說一下問題,對于程序:
float a = 123456.789e5; float b = a + 20; printf("%fn", b);將輸出什么?是12345678920.000000 嗎?
下面僅考慮 float 為使用 IEEE 754 32 位單精度浮點數的情況,
即 float 為 32 位,其中 1 為符號位,接下來,8 位階碼,最后,23 位尾碼
任何一個浮點數(除 0 以外),都可以表示為:
V = (-1)^s * M * 2^E
接下來分析這個數:
123456.789e5
= 12345678900
= 8589934592 + 2147483648 + 1073741824 + 268435456 + 134217728 + 67108864 + 33554432 + 16777216 + 8388608 + 4194304 + 1048576 + 524288 + 262144 + 4096 + 2048 + 1024 + 32 + 16 + 4
= 2^33 + 2^31 + 2^30 +2^28 + 2^27 + 2^26 + 2^25+2^24+2^23 + 2^22 + 2^20 + 2^19 + 2^18 + 2^12+2^11 + 2^10 + 2^5 + 2^4 + 2^2
= 10 1101 1111 1101 1100 0001 1100 0011 0100(二進制)
= 1.0 1101 1111 1101 1100 0001 1100 0011 0100 * 2^33 (二進制)
此數大于 0,所以符號位部分存儲為 0
此數,階碼為33,偏移量為 127,33 + 127 = 160 = 1010 0000,
階碼部分存儲為 1010 0000
如上所述,對于 1.0 1101 1111 1101 1100 0001 1100 0011 0100,最前面的 1 不存儲,只存儲小數位,由于,尾碼只有 23 為,而 1.0 1101 1111 1101 1100 0001 1100 0011 0100,小數部分有 33 位,所以只能忽略點最后 10 位,即,尾碼部分為 011 0111 1111 0111 0000 0111(此處損失了精度)
最后此數在計算機內表示為:0101 0000 0011 0111 1111 0111 0000 0111
將其轉化為浮點數為:12345678848.000000,所以,float 類型的 123456.789e5 在計算機內表示為:12345678848.000000
接下來,在考慮 a + 20,int 和 float 相加,int 將先轉換為 float
所以,20 = 2^4 + 2^2 = 1.01 * 2 ^ 4,即:
符號位表示為:0
階碼為 4,加上偏移量 127,4 + 127 = 131 = 1000 0011,階碼部分存儲為 1000 0011
尾碼,對于 1.01 不存儲最前面的 1,階碼共 23 位 ,而小數部分只有兩位,不足用 0 填,所以,尾碼,存儲為:010 0000 0000 0000 0000 0000
所以 float 類型的 20,存儲為 0100 0001 1010 0000 0000 0000 0000 0000
現在,再考慮兩數相加,
0101 0000 0011 0111 1111 0111 0000 0111(123456.789e5)
0100 0001 1010 0000 0000 0000 0000 0000(20)
首先,進行,階碼對齊,123456.789e5 的階碼為:1010 0000(160),20 的階碼為 1000 0011(130),
小階碼向大階碼對齊,所以,將 0100 0001 1010 0000 0000 0000 0000 0000(20)的階碼轉化為 1010 0000 (160),將尾碼(包括未存儲的 1)向右移 30 位,空位用 0 填充, 即轉換為 0101 0000 0(0)000 0000 0000 0000 0000 0000(此處有精度損失)
現在:
0101 0000 0(1)011 0111 1111 0111 0000 0111(123456.789e5)
0101 0000 0(0)000 0000 0000 0000 0000 0000(20)
接下來,階碼不變,由于兩數都是正數,所以尾碼相加(需要加上尾碼未存儲的1),尾碼部分結果為:(1)011 0111 1111 0111 0000 0111
然后,進行格式化,這個例子不需要格式化,(此步可能損失精度)
所以,加上符號位和階碼,最終結果為:
0101 0000 0011 0111 1111 0111 0000 0111(12345678848.000000)
結論:浮點數,進行存儲或運算時,可能會有精度損失
此外,還有幾個特殊的浮點數:
0000 0000 0000 0000 0000 0000 0000 0000
2. 符號位為 1,指數部分,尾數部分都為 0,表示 -0.0
1000 0000 0000 0000 0000 0000 0000 0000
3. 符號位為 0,指數部分都為 1,尾數部分都為 0,表示正無窮大
0111 1111 1000 0000 0000 0000 0000 0000
4. 符號位為 1,指數部分都為 1,尾數部分都為 0,表示負無窮大
1111 1111 1000 0000 0000 0000 0000 0000
5. 符號位無所謂,指數部分都為 1,尾數部分為非 0,表示不是一個數字,是 NaN
*111 1111 1 + 非0
總結
以上是生活随笔為你收集整理的3 float py 位小数 裁剪_对一个 float 精度问题的分析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: beetl 页面标签_05.Beetl标
- 下一篇: hibernate mysql casc