摘要:本篇文章會(huì)講述浮點(diǎn)數(shù)的設(shè)計(jì)原理,比如如何存儲(chǔ)二進(jìn)制的問題既峡,從而幫助我們更好的編碼。
__1. deading code __
console.log(1.0-0.9 == 0.1);
//輸出 false
console.log(1.0-0.9, 0.1);
//輸出 0.09999999999999998 0.1
//所以判斷浮點(diǎn)運(yùn)算結(jié)果前要對(duì)參數(shù)進(jìn)行精度縮小,縮小精度會(huì)四舍五入闸准。
console.log(parseFloat((1.0-0.9).toFixed(10)) == 0.1);
//輸出 true
console.log(parseFloat((1.0-0.9).toFixed(10)),0.1)
//輸出 0.1 0.1
所以使用 JavaScript 設(shè)計(jì)浮點(diǎn)數(shù)計(jì)算時(shí)霎奢,要考慮小數(shù)不準(zhǔn)確的問題户誓。
2.浮點(diǎn)數(shù)二進(jìn)制存儲(chǔ)
如 32 存儲(chǔ)為例來講解存儲(chǔ)。
Sign | Exponent | Mantissa |
---|---|---|
1bit | 8bits | 23bits |
- Sign:表示浮點(diǎn)數(shù)是正數(shù)還是負(fù)數(shù)幕侠。0表示正數(shù)帝美,1表示負(fù)數(shù)
- Exponent:指數(shù)部分。類似于科學(xué)技術(shù)法中的M*10^N中的 N晤硕,要注意規(guī)定
01111111 = 2^0 也就是 0悼潭,所以指數(shù)部分可以表達(dá): -128 - 127。 - Mantissa:基數(shù)部分舞箍。浮點(diǎn)數(shù)具體數(shù)值的實(shí)際表示舰褪。
嘗試把 3.1 轉(zhuǎn)換成二進(jìn)制存儲(chǔ):
- 是正數(shù)第一位是 0。
- 3 轉(zhuǎn)換成二進(jìn)制 11疏橄。
- 0.1 轉(zhuǎn)換成二進(jìn)制占拍,__0.1 __ 轉(zhuǎn)換成 0.0625+0.007825+0.00390625... 即 2-3+2-4+2^7....,二進(jìn)制為 .00011001100110011001100 捎迫,是1100無限循環(huán)晃酒,保留到23位。(這里確實(shí)有點(diǎn)繞立砸,不理解的單獨(dú)查資料能更快了解掖疮。也就是這里導(dǎo)致小數(shù)在計(jì)算機(jī)里的存儲(chǔ)會(huì)不準(zhǔn)確,是一個(gè)近似值颗祝。
- 整數(shù)和小數(shù)合并為 11.0001100110011001100110 , 然后保證小數(shù)點(diǎn)以前只有一位數(shù)浊闪,1.10001100110011001100110 * 2^1。
- 合并后小數(shù)點(diǎn)前的一位數(shù)是要舍去的螺戳,由于我們上一個(gè)步驟搁宾,小數(shù)點(diǎn)前的數(shù)字總會(huì)為 1,所以為了減少存儲(chǔ)我們舍去 . 前的為1數(shù)字倔幼,最后得 .100011001100110011001100 * 2^1盖腿。
- 指數(shù)轉(zhuǎn)換,由上一步得指數(shù)為 __2^1 __,由于規(guī)定 01111111 = 2^0(這樣的目的就是為了翩腐,指數(shù)可以為正也可以為負(fù))鸟款, 2^1 為 10000000 ,合并后得
10000000 10001100110011001100110 - 添上第一位代表正負(fù) 0 10000000 10001100110011001100110 最終__ 3.1 __被用二進(jìn)制表達(dá)茂卦。
其中最重要的部分是小數(shù)轉(zhuǎn)二進(jìn)制何什,像 0.5、0.25等龙、0.125 這樣的小數(shù)轉(zhuǎn)化二進(jìn)制為 0.1处渣、0.01、0.001 蛛砰,但是 0.1罐栈、0.2 就不好表示了。如果不理解百度有在線二轉(zhuǎn)十進(jìn)制 地址
驗(yàn)證的網(wǎng)址:https://www.h-schmidt.net/FloatConverter/IEEE754.html
3.猜想
語言還沒有組織好泥畅。