日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

Java浮点数内存存储

發布時間:2024/4/17 java 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java浮点数内存存储 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

轉自:

【解惑】剖析float型的內存存儲和精度丟失問題

1、小數的二進制表示問題

???????首先我們要搞清楚下面兩個問題:

???? (1)? 十進制整數如何轉化為二進制數

?????????? 算法很簡單。舉個例子,11表示成二進制數:

???????????????????? 11/2=5 ? 余?? 1

? ? ? ? ? ? ? ? ? ? ? 5/2=2?? 余?? 1

? ? ? ? ? ? ? ? ? ? ? 2/2=1?? 余?? 0

? ? ? ? ? ? ? ? ? ? ? 1/2=0?? 余?? 1

????????????????????????? 0 ? 結束????????

? ? ? ? ?所以:11二進制表示為(從下往上):1011

? ? ? ? ?這里提一點:只要遇到除以后的結果為0了就結束了,大家想一想,所有的整數除以2是不是一定能夠最終得到0。換句話說,所有的整數轉變為二進制數的算法會不會無限循環下去呢?絕對不會,整數永遠可以用二進制精確表示?,但小數就不一定了。

????? (2) 十進制小數如何轉化為二進制數

?????????? 算法是乘以2直到沒有了小數為止。舉個例子,0.9表示成二進制數

???????????????????? 0.9*2=1.8 ? ? ? ? ? ? ? ? ? 取整數部分? 1

???????????????????? 0.8(1.8的小數部分)*2=1.6??? 取整數部分? 1

???????????????????? 0.6*2=1.2??         取整數部分? 1

???????????????????? 0.2*2=0.4??         取整數部分? 0

???????????????????? 0.4*2=0.8??         取整數部分? 0

???????????????????? 0.8*2=1.6 ?         取整數部分? 1

???????????????????? 0.6*2=1.2??         取整數部分? 0

? ? ? ? ? ? ? ? ? ? ?.........?????

    所以:0.9二進制表示為(從上往下): 11100100100100......

?????????? 注意:上面的計算過程循環了,也就是說*2永遠不可能消滅小數部分,這樣算法將無限下去。很顯然,小數的二進制表示有時是不可能精確的?。其實道理很簡單,十進制系統中能不能準確表示出1/3呢?同樣二進制系統也無法準確表示1/10。這也就解釋了為什么浮點型減法出現了"減不盡"的精度丟失問題。

?

2、?float型在內存中的存儲?

???? 眾所周知、?Java 的float型在內存中占4個字節。float的32個二進制位結構如下

? ? ? ???float內存存儲結構 :

表示符號位指數符號位指數位有效數位
4bytes313029-2322-0

? ? ? ?

??????? 其中符號位1表示正,0表示負。有效位數位24位,其中一位是實數符號位。

?

將一個float型轉化為內存存儲格式的步驟為:

? (1)先將這個實數的絕對值化為二進制格式,注意實數的整數部分和小數部分的二進制方法在上面已經探討過了。?
? (2)將這個二進制格式實數的小數點左移或右移n位,直到小數點移動到第一個有效數字的右邊。?
? (3)從小數點右邊第一位開始數出二十三位數字放入第22到第0位。?
? (4)如果實數是正的,則在第31位放入“0”,否則放入“1”。?
? (5)如果n 是左移得到的,說明指數是正的,第30位放入“1”。如果n是右移得到的或n=0,則第30位放入“0”。?
? (6)如果n是左移得到的,則將n減去1后化為二進制,并在左邊加“0”補足七位,放入第29到第23位。如果n是右移得到的或n=0,則將n化為二進制后在左邊加“0”補足七位,再各位求反,再放入第29到第23位。

?舉例說明: 11.9的內存存儲格式

?????? (1) 將11.9化為二進制后大約是"?1011.?1110011001100110011001100..."。

?????? (2) 將小數點左移三位到第一個有效位右側:?"1.?011?11100110011001100110?"。?保證有效位數24位,右側多余的截取(誤差在這里產生了?)。

?????? (3)?這已經有了二十四位有效數字,將最左邊一位“1”去掉,得到“?011?11100110011001100110?”共23bit。將它放入float存儲結構的第22到第0位。

?????? (4) 因為11.9是正數,因此在第31位實數符號位放入“0”。

?????? (5) 由于我們把小數點左移,因此在第30位指數符號位放入“1”。

?????? (6) 因為我們是把小數點左移3位,因此將3減去1得2,化為二進制,并補足7位得到0000010,放入第29到第23位。

?

? ? ? 最后表示11.9為:??0?1?0000010?011?11100110011001100110

?

?再舉一個例子:0.2356的內存存儲格式
?? ?? (1)將0.2356化為二進制后大約是0.00111100010100000100100000。?
????? (2)將小數點右移三位得到1.11100010100000100100000。?
????? (3)從小數點右邊數出二十三位有效數字,即11100010100000100100000放入第22到第0位。?
????? (4)由于0.2356是正的,所以在第31位放入“0”。?
????? (5)由于我們把小數點右移了,所以在第30位放入“0”。?
????? (6)因為小數點被右移了3位,所以將3化為二進制,在左邊補“0”補足七位,得到0000011,各位取反,得到1111100,放入第29到第23位。?
???????

? ? ?最后表示0.2356為:0?0?1111100?11100010100000100100000

?

將一個內存存儲的float二進制格式轉化為十進制的步驟:?
???? (1)將第22位到第0位的二進制數寫出來,在最左邊補一位“1”,得到二十四位有效數字。將小數點點在最左邊那個“1”的右邊。?
???? (2)取出第29到第23位所表示的值n。當30位是“0”時將n各位求反。當30位是“1”時將n增1。?
???? (3)將小數點左移n位(當30位是“0”時)或右移n位(當30位是“1”時),得到一個二進制表示的實數。?
???? (4)將這個二進制實數化為十進制,并根據第31位是“0”還是“1”加上正號或負號即可。

?

3、浮點型的減法運算

? ? ?浮點加減運算過程比定點運算過程復雜。完成浮點加減運算的操作過程大體分為四步:???
? ??(1) 0操作數的檢查;

? ? ? ? ? ?如果判斷兩個需要加減的浮點數有一個為0,即可得知運算結果而沒有必要再進行有序的一些列操作。?

   (2) 比較階碼(指數位)大小并完成對階;

? ? ? 兩浮點數進行加減,首先要看兩數的?指數位?是否相同,即小數點位置是否對齊。若兩數?指數位?相同,表示小數點是對齊的,就可以進行尾數的加減運算。反之,若兩數階碼不同,表示小數點位置沒有對齊,此時必須使兩數的階碼相同,這個過程叫做對階?。

????????如何對階(假設兩浮點數的指數位為?Ex?和?Ey?):

????????通過尾數的移位以改變?Ex?或?Ey?,使之相等。?由于浮點表示的數多是規格化的,尾數左移會引起最高有位的丟失,造成很大誤差;而尾數右移雖引起最低有效位的丟失,但造成的誤差較小,因此,對階操作規定 使尾數右移,尾數右移后使階碼作相應增加,其數值保持不變。很顯然,一個增加后的階碼與另一個相等,所增加的階碼一定是小階。因此在對階時,總是使小階向大階看齊?,即小階的尾數向右移位?(?相當于小數點左移?)?,每右移一位,其階碼加?1?,直到兩數的階碼相等為止,右移的位數等于階差?△?E?。?
   (3) 尾數(有效數位)進行加或減運算;

? ? ? ? ?對階完畢后就可有效數位求和。?不論是加法運算還是減法運算,都按加法進行操作,其方法與定點加減運算完全一樣。?
   (4) 結果規格化并進行舍入處理。

????????????????略

?浮點數的加減法:具體見http://www.zzslxx.com/wmy/jy/Chap02/2.7.1.htm

?

4、?計算12.0f-11.9f

?

? ? ?12.0f 的內存存儲格式為:? ??0?1?0000010?10000000000000000000000? ???

???? 11.9f 的內存存儲格式為:?? ??0?1?0000010?011?11100110011001100110

?

???? 可見兩數的指數位完全相同,只要對有效數位進行減法即可。

???? 12.0f-11.9f?? 結果:?????????0?1?0000010?00000011001100110011010

???? 將結果還原為十進制為: 0.000?11001100110011010=?0.10000038

?

轉載于:https://www.cnblogs.com/loren-Yang/p/7519593.html

總結

以上是生活随笔為你收集整理的Java浮点数内存存储的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。