根據(jù)國際標(biāo)準(zhǔn)IEEE 754甚侣,任意一個二進(jìn)制浮點(diǎn)數(shù)V可以表示成下面的形式:
![(1)(-1)^s表示符號位示血,當(dāng)s=0混移,V為正數(shù)廓译;當(dāng)s=1,V為負(fù)數(shù)乙濒。
(2)M表示有效數(shù)字陕赃,大于等于1,小于2。
(3)2^E表示指數(shù)位么库。
IEEE754標(biāo)準(zhǔn)中規(guī)定float單精度浮點(diǎn)數(shù)在機(jī)器中表示用 1 位表示數(shù)字的符號傻丝,用 8 位來表示指數(shù),用23 位來表示尾數(shù)诉儒,即小數(shù)部分桑滩。對于double雙精度浮點(diǎn)數(shù),用 1 位表示符號允睹,用 11 位表示指數(shù),52 位表示尾數(shù)幌氮,其中指數(shù)域稱為階碼缭受。
題目中的32位浮點(diǎn)數(shù),可以寫為 S+E+M 三部分的形式:0 10000101 11011010000000000000000
F87AF9B3-96A6-4892-BBD7-107968F22B5B.png
IEEE 754對有效數(shù)字M和指數(shù)E该互,還有一些特別規(guī)定米者。
有效數(shù)字 M ,1≤M<2宇智,也就是說蔓搞,M可以寫成1.xxxxxx的形式,其中xxxxxx表示小數(shù)部分随橘。IEEE 754規(guī)定喂分,在計(jì)算機(jī)內(nèi)部保存M時,默認(rèn)這個數(shù)的第一位總是1机蔗,因此可以被舍去蒲祈,只保存后面的xxxxxx部分。比如保存1.01的時候萝嘁,只保存01梆掸,等到讀取的時候,再把第一位的1加上去牙言。這樣做的目的酸钦,是節(jié)省1位有效數(shù)字。以32位浮點(diǎn)數(shù)為例咱枉,留給M只有23位卑硫,將第一位的1舍去以后,等于可以保存24位有效數(shù)字庞钢。
至于指數(shù)E,首先拔恰,E為一個無符號整數(shù)(unsigned int)。這意味著基括,如果E為8位颜懊,它的取值范圍為0-255;如果E為11位,它的取值范圍為0-2047河爹。但是匠璧,我們知道,科學(xué)計(jì)數(shù)法中的E是可以出現(xiàn)負(fù)數(shù)的咸这,所以IEEE 754規(guī)定夷恍,E的真實(shí)值必須再減去一個中間數(shù),對于8位的E媳维,這個中間數(shù)是127酿雪;對于11位的E,這個中間數(shù)是1023侄刽。
指數(shù)E還可以再分成三種情況:
E不全為0或不全為1指黎。
這時,浮點(diǎn)數(shù)就采用上面的規(guī)則表示州丹,即指數(shù)E的計(jì)算值減去127(或1023)醋安,得到真實(shí)值,再將有效數(shù)字M前加上第一位的1墓毒。
E全為0吓揪。
這時,浮點(diǎn)數(shù)的指數(shù)E等于1-127(或者1-1023)所计,有效數(shù)字M不再加上第一位的1柠辞,而是還原為0.xxxxxx的小數(shù)。這樣做是為了表示±0醉箕,以及接近于0的很小的數(shù)字钾腺。
E全為1。
這時讥裤,如果有效數(shù)字M全為0放棒,表示±無窮大(正負(fù)取決于符號位s);如果有效數(shù)字M不全為0己英,表示這個數(shù)不是一個數(shù)(NaN)间螟。
舉例來說,
十進(jìn)制的5.0损肛,寫成二進(jìn)制是101.0厢破,相當(dāng)于1.01×2^2。那么治拿,按照上面V的格式摩泪,可以得出s=0,M=1.01劫谅,E=2见坑。
十進(jìn)制的-5.0嚷掠,寫成二進(jìn)制是-101.0,相當(dāng)于-1.01×2^2荞驴。那么不皆,s=1,M=1.01熊楼,E=2霹娄。
JS 中的最大安全整數(shù)是多少?
JS 中所有的數(shù)字類型鲫骗,實(shí)際存儲都是通過 8 字節(jié) double 浮點(diǎn)型 表示的犬耻。浮點(diǎn)數(shù)并不是能夠精確表示范圍內(nèi)的所有數(shù)的, 雖然 double 浮點(diǎn)型的范圍看上去很大: 2.23x10^(-308) ~ 1.79x10^308执泰。 可以表示的最大整數(shù)可以很大香追,但能夠精確表示,使用算數(shù)運(yùn)算的并沒有這么大坦胶。
它其實(shí)連這樣的簡單加法也會算錯:
所以在 js 中能夠安全使用的有符號 安全 大整數(shù)(注意這里是指能夠安全使用,進(jìn)行算數(shù)運(yùn)算的范圍)晴楔,并不像其他語言在 64 位環(huán)境中那樣是:
而是
JS 的最大和最小安全值可以這樣獲得:
通過下面的例子顿苇,你會明白為什么大于這個值的運(yùn)算是不安全的:
這些運(yùn)算都是錯誤的結(jié)果, 因?yàn)樗鼈冞M(jìn)行的都是浮點(diǎn)數(shù)運(yùn)算會丟失精度税弃。
為什么是這個值?
double 浮點(diǎn)數(shù)結(jié)構(gòu)如下:
1 位符號位
11 位指數(shù)位
52 位尾數(shù)位
使用 52 位表示一個數(shù)的整數(shù)部分纪岁,那么最大可以精確表示的數(shù)應(yīng)該是 2^52 - 1 才對, 就像 64 位表示整數(shù)時那樣: 2^63 - 1 (去掉 1 位符號位)则果。 但其實(shí)浮點(diǎn)數(shù)在保存數(shù)字的時候做了規(guī)格化處理幔翰,以 10 進(jìn)制為例:
對于二進(jìn)制來說, 小數(shù)點(diǎn)前保留一位西壮, 規(guī)格化后始終是 1.***, 節(jié)省了 1 bit遗增,這個 1 并不需要保存。
解決浮點(diǎn)數(shù)溢出的辦法
使用toFixed方法返回一個以定點(diǎn)表示法表示的數(shù)字的字符串形式
調(diào)用一個處理函數(shù)
參考文章:http://www.ruanyifeng.com/blog/2010/06/ieee_floating-point_representation.html