中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何分析Java?float和double精度范圍大小

發布時間:2021-12-13 12:44:13 來源:億速云 閱讀:217 作者:柒染 欄目:開發技術

如何分析Java float和double精度范圍大小,針對這個問題,這篇文章詳細介紹了相對應的分析和解答,希望可以幫助更多想解決這個問題的小伙伴找到更簡單易行的方法。

    Java float和double精度范圍大小

    要想理解float和double的取值范圍和計算精度,必須先了解小數是如何在計算機中存儲的:

    舉個例子:78.375,是一個正小數。要在計算機中存儲這個數,需要把它表示為浮點數的格式,先執行二進制轉換:

    一、小數的二進制轉換(浮點數)

    78.375的整數部分:

    如何分析Java?float和double精度范圍大小

    小數部分:

    如何分析Java?float和double精度范圍大小

    所以,78.375的二進制形式就是1001110.011

    然后,使用二進制科學記數法,有

    如何分析Java?float和double精度范圍大小

    注意,轉換后用二進制科學記數法表示的這個數,有底有指數有小數部分,這個就叫做浮點數

    二、浮點數在計算機中的存儲

    在計算機中,保存這個數使用的是浮點表示法,分為三大部分:

    • 第一部分用來存儲符號位(sign),用來區分正負數這里是0,表示正數

    • 第二部分用來存儲指數(exponent),這里的指數是十進制的6

    • 第三部分用來存儲小數(fraction),這里的小數部分是001110011

    需要注意的是,指數也有正負之分,后面再講。

    如下圖所示(圖片來自維基百科):

    如何分析Java?float和double精度范圍大小

    比如float類型是32位,是單精度浮點表示法:

    • 符號位(sign)占用1位,用來表示正負數,

    • 指數位(exponent)占用8位,用來表示指數,

    • 小數位(fraction)占用23位,用來表示小數,不足位數補0。

    而double類型是64位,是雙精度浮點表示法:

    • 符號位占用1位,指數位占用11位,小數位占用52位。

    到這里其實已經可以隱隱看出:

    • 指數位決定了大小范圍,因為指數位能表示的數越大則能表示的數越大嘛!

    • 而小數位決定了計算精度,因為小數位能表示的數越大,則能計算的精度越大咯!

    可能還不夠明白,舉例子吧:

    • float的小數位只有23位,即二進制的23位,能表示的最大的十進制數為2的23次方,即8388608,即十進制的7位,嚴格點,精度只能百分百保證十進制的6位運算。

    • double的小數位有52位,對應十進制最大值為4 503 599 627 370 496,這個數有16位,所以計算精度只能百分百保證十進制的15位運算。

    三、指數位的偏移量與無符號表示

    需要注意的是指數可能是負數,也有可能是正數,即指數是有符號整數,而有符號整數的計算是比無符號整數麻煩的。所以為了減少不必要的麻煩,在實際存儲指數的時候,需要把指數轉換成無符號整數。那么怎么轉換呢?

    注意到float的指數部分是8位,則指數的取值范圍是 -126到+127,為了消除負數帶來的實際計算上的影響(比如比較大小,加減法等),可以在實際存儲的時候,給指數做一個簡單的映射,加上一個偏移量,比如float的指數偏移量為127,這樣就不會有負數出現了

    比如

    • 指數如果是6,則實際存儲的是6+127=133,即把133轉換為二進制之后再存儲。

    • 指數如果是-3,則實際存儲的是-3+127=124,即把124轉換為二進制之后再存儲。

    當我們需要計算實際代表的十進制數的時候,再把指數減去偏移量即可。

    對應的double類型,存儲的時候指數偏移量是1023。

    四、小結一下

    所以用float類型來保存十進制小數78.375的話,需要先轉換成浮點數,得到符號位指數小數部分

    這個例子前面已經分析過,所以:

    符號位是0,

    指數位是6+127=133,二進制表示為10 000 101,

    小數部分是001110011,不足部分請自動補0。

    連起來用float表示,加粗部分是指數位,最左邊是符號位0,代表正數:

    0 10000101 001110011 00000 00000 0000

    如果用double來保存。。。自己計算吧,太多0了。

    float和double的范圍到底是多少

    Java中float占4個字節,32bit。計算范圍公式為 ((-1)^S)* (2^(E-127))*(1.M) ,其中S占一位是符號位,E所占8bit是指數位,M占23位是尾數位。

    這里一開始(1.M)部分一開始我一直沒想明白為什么前面是1,突然有一天腦子開竅了,科學計數法表示的時候小數點前面就必須是1,所以規格化的時候小數點前面是1。

    E占8位,所以大小是0-255,但是為了表示小數,指數部分需要可以是小數,對半一分,所以最后是E-127,也就是說指數部分為-127-128。

    尾數部分沒什么好說的,范圍就是1-1.11……(23位全是1)

    注意 :尾數這里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

    總結一下上面的,按道理最大值應該是(2^128)*(2-2^(-23))=2^129-2^105=6.81*10^38,但是一般書上說的都是3.40*10^38,那么問題又來了,為什么會大了2倍?

    排除掉所有出書的人抄來抄去的行為導致所有的書都錯了這個因素,那么剩下的只能是上面某個地方出了問題。首先,回到上面那個我加粗的規格化上去(我個人覺得完全可以用一般情況來代替這個詞),仔細想想,假如所有的數都是上面那種規格化表示的時候:

    第一:得到的數永遠是(1.M)乘以一個數,指數部分是不會為0的,那么0怎么表示?

    第二:無窮大和無窮小,還有NAN(not a number)又是怎么用這32bit表示出來的?我曾經想過的一個解釋是,計算機里沒有那個數就表示NAN嘛。。。以前還真覺得這個好有道理來著。但是計算機這個東西你只能當做一個工具,也就是說它不能無中生有,它只能處理我們給它的東西,所有無窮大無窮小還有NAN在計算機里肯定有一種表示方式。

    所以,一定還有非規格化的表示,也就是所謂的特殊情況。

    第一:當E是8個0的時候,此時就不是(1.M)而是(0.M)了,這個時候就可以表示出0了,當然還可以表示那些非常接近0的數。

    第二:當E是8個1的時候,如果小數域全是0,表示的是無窮,其余的表示NAN。

    由上可知,指數部分為(0-127)和(255-127)的時候表示的是兩種特殊情況,所以E的范圍應該是【-126,127】。最后,得出的結論是規格化的浮點數的表示范圍是 正負(2^127)*(2-2^(-23))=2^128-2^104=3.40*10^38

    關于如何分析Java float和double精度范圍大小問題的解答就分享到這里了,希望以上內容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關注億速云行業資訊頻道了解更多相關知識。

    向AI問一下細節

    免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

    AI

    福州市| 开化县| 双牌县| 卓尼县| 西青区| 娱乐| 绥阳县| 广安市| 沙坪坝区| 高邮市| 布尔津县| 鄂州市| 沙田区| 三台县| 容城县| 龙口市| 资中县| 安西县| 米泉市| 密山市| 洪泽县| 内黄县| 冷水江市| 大英县| 富平县| 福贡县| 探索| 新龙县| 滨州市| 新干县| 盘锦市| 紫云| 达州市| 平度市| 昌黎县| 峨山| 遂平县| 汽车| 光泽县| 宣恩县| 大同县|