關(guān)于Java?float和double精度范圍大小
Java float和double精度范圍大小
要想理解float和double的取值范圍和計算精度,必須先了解小數(shù)是如何在計算機中存儲的:
舉個例子:78.375,是一個正小數(shù)。要在計算機中存儲這個數(shù),需要把它表示為浮點數(shù)的格式,先執(zhí)行二進制轉(zhuǎn)換:
一、小數(shù)的二進制轉(zhuǎn)換(浮點數(shù))
78.375的整數(shù)部分:

小數(shù)部分:

所以,78.375的二進制形式就是1001110.011
然后,使用二進制科學(xué)記數(shù)法,有

注意,轉(zhuǎn)換后用二進制科學(xué)記數(shù)法表示的這個數(shù),有底有指數(shù)有小數(shù)部分,這個就叫做浮點數(shù)
二、浮點數(shù)在計算機中的存儲
在計算機中,保存這個數(shù)使用的是浮點表示法,分為三大部分:
- 第一部分用來存儲符號位(sign),用來區(qū)分正負(fù)數(shù),這里是0,表示正數(shù)
- 第二部分用來存儲指數(shù)(exponent),這里的指數(shù)是十進制的6
- 第三部分用來存儲小數(shù)(fraction),這里的小數(shù)部分是001110011
需要注意的是,指數(shù)也有正負(fù)之分,后面再講。
如下圖所示(圖片來自維基百科):

比如float類型是32位,是單精度浮點表示法:
- 符號位(sign)占用1位,用來表示正負(fù)數(shù),
- 指數(shù)位(exponent)占用8位,用來表示指數(shù),
- 小數(shù)位(fraction)占用23位,用來表示小數(shù),不足位數(shù)補0。
而double類型是64位,是雙精度浮點表示法:
- 符號位占用1位,指數(shù)位占用11位,小數(shù)位占用52位。
到這里其實已經(jīng)可以隱隱看出:
- 指數(shù)位決定了大小范圍,因為指數(shù)位能表示的數(shù)越大則能表示的數(shù)越大嘛!
- 而小數(shù)位決定了計算精度,因為小數(shù)位能表示的數(shù)越大,則能計算的精度越大咯!
可能還不夠明白,舉例子吧:
- float的小數(shù)位只有23位,即二進制的23位,能表示的最大的十進制數(shù)為2的23次方,即8388608,即十進制的7位,嚴(yán)格點,精度只能百分百保證十進制的6位運算。
- double的小數(shù)位有52位,對應(yīng)十進制最大值為4 503 599 627 370 496,這個數(shù)有16位,所以計算精度只能百分百保證十進制的15位運算。
三、指數(shù)位的偏移量與無符號表示
需要注意的是指數(shù)可能是負(fù)數(shù),也有可能是正數(shù),即指數(shù)是有符號整數(shù),而有符號整數(shù)的計算是比無符號整數(shù)麻煩的。所以為了減少不必要的麻煩,在實際存儲指數(shù)的時候,需要把指數(shù)轉(zhuǎn)換成無符號整數(shù)。那么怎么轉(zhuǎn)換呢?
注意到float的指數(shù)部分是8位,則指數(shù)的取值范圍是 -126到+127,為了消除負(fù)數(shù)帶來的實際計算上的影響(比如比較大小,加減法等),可以在實際存儲的時候,給指數(shù)做一個簡單的映射,加上一個偏移量,比如float的指數(shù)偏移量為127,這樣就不會有負(fù)數(shù)出現(xiàn)了。
比如
- 指數(shù)如果是6,則實際存儲的是6+127=133,即把133轉(zhuǎn)換為二進制之后再存儲。
- 指數(shù)如果是-3,則實際存儲的是-3+127=124,即把124轉(zhuǎn)換為二進制之后再存儲。
當(dāng)我們需要計算實際代表的十進制數(shù)的時候,再把指數(shù)減去偏移量即可。
對應(yīng)的double類型,存儲的時候指數(shù)偏移量是1023。
四、小結(jié)一下
所以用float類型來保存十進制小數(shù)78.375的話,需要先轉(zhuǎn)換成浮點數(shù),得到符號位和指數(shù)和小數(shù)部分。
這個例子前面已經(jīng)分析過,所以:
符號位是0,
指數(shù)位是6+127=133,二進制表示為10 000 101,
小數(shù)部分是001110011,不足部分請自動補0。
連起來用float表示,加粗部分是指數(shù)位,最左邊是符號位0,代表正數(shù):
0 10000101 001110011 00000 00000 0000
如果用double來保存。。。自己計算吧,太多0了。
float和double的范圍到底是多少
Java中float占4個字節(jié),32bit。計算范圍公式為 ((-1)^S)* (2^(E-127))*(1.M) ,其中S占一位是符號位,E所占8bit是指數(shù)位,M占23位是尾數(shù)位。
這里一開始(1.M)部分一開始我一直沒想明白為什么前面是1,突然有一天腦子開竅了,科學(xué)計數(shù)法表示的時候小數(shù)點前面就必須是1,所以規(guī)格化的時候小數(shù)點前面是1。
E占8位,所以大小是0-255,但是為了表示小數(shù),指數(shù)部分需要可以是小數(shù),對半一分,所以最后是E-127,也就是說指數(shù)部分為-127-128。
尾數(shù)部分沒什么好說的,范圍就是1-1.11……(23位全是1)
注意 :尾數(shù)這里1.1111實際上是 十進制的1 + 二進制的0.1111, 什么意思呢, 舉例說明會清楚一點:
1.1 ----> 1+1/2 = 1.5 = 2-1/2
1.11 -----> 1+1/2 +1/4 = 1.75 = 2-1/4
總結(jié)一下上面的
按道理最大值應(yīng)該是(2^128)*(2-2^(-23))=2^129-2^105=6.81*10^38,但是一般書上說的都是3.40*10^38,那么問題又來了,為什么會大了2倍?
排除掉所有出書的人抄來抄去的行為導(dǎo)致所有的書都錯了這個因素,那么剩下的只能是上面某個地方出了問題。首先,回到上面那個我加粗的規(guī)格化上去(我個人覺得完全可以用一般情況來代替這個詞),仔細(xì)想想,假如所有的數(shù)都是上面那種規(guī)格化表示的時候:
第一:得到的數(shù)永遠是(1.M)乘以一個數(shù),指數(shù)部分是不會為0的,那么0怎么表示?
第二:無窮大和無窮小,還有NAN(not a number)又是怎么用這32bit表示出來的?我曾經(jīng)想過的一個解釋是,計算機里沒有那個數(shù)就表示NAN嘛。。。以前還真覺得這個好有道理來著。但是計算機這個東西你只能當(dāng)做一個工具,也就是說它不能無中生有,它只能處理我們給它的東西,所有無窮大無窮小還有NAN在計算機里肯定有一種表示方式。
所以,一定還有非規(guī)格化的表示,也就是所謂的特殊情況。
第一:當(dāng)E是8個0的時候,此時就不是(1.M)而是(0.M)了,這個時候就可以表示出0了,當(dāng)然還可以表示那些非常接近0的數(shù)。
第二:當(dāng)E是8個1的時候,如果小數(shù)域全是0,表示的是無窮,其余的表示NAN。
由上可知,指數(shù)部分為(0-127)和(255-127)的時候表示的是兩種特殊情況,所以E的范圍應(yīng)該是【-126,127】。最后,得出的結(jié)論是規(guī)格化的浮點數(shù)的表示范圍是 正負(fù)(2^127)*(2-2^(-23))=2^128-2^104=3.40*10^38
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
深入探究SpringBoot攔截器的自定義設(shè)計與實現(xiàn)全攻略
攔截器是Spring框架提供的核心功能之?,主要用來攔截用戶的請求,在指定方法前后,根據(jù)業(yè)務(wù)需要執(zhí)行預(yù)先設(shè)定的代碼,本文將給大家和大家一起深入探究SpringBoot攔截器的自定義設(shè)計與實現(xiàn),需要的朋友可以參考下2024-05-05
maven如何打包動態(tài)環(huán)境變量(包括啟動腳本)
這篇文章主要介紹了maven如何打包動態(tài)環(huán)境變量(包括啟動腳本)問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-04-04
分析Spring框架之設(shè)計與實現(xiàn)資源加載器
Spring框架是由于軟件開發(fā)的復(fù)雜性而創(chuàng)建的。然而,Spring的用途不僅僅限于服務(wù)器端的開發(fā)。從簡單性、可測試性和松耦合性角度而言,絕大部分Java應(yīng)用都可以從Spring中受益。今天來分析它的設(shè)計與實現(xiàn)資源加載器,從Spring.xml解析和注冊Bean對象2021-06-06
Spring Security 在 Spring Boot 中的使用詳解【集中式】
這篇文章主要介紹了Spring Security 在 Spring Boot 中的使用【集中式】,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-10-10
Spring注解中@Autowired和@Bean的區(qū)別詳解
這篇文章主要詳細(xì)介紹了Spring注解中@Autowired和@Bean二者有什么區(qū)別,文中通過兩個注解的使用場景介紹了二者的區(qū)別,感興趣的同學(xué)可以參考閱讀2023-06-06

