Java中float,double為什麼會丟失精度。
Effective Java Item 48: Avoid float and double if exact answers are required
對於精確計算不提倡使用float,double,因為會丟失精度,這是為什麼呢? 讓我細細說來
1. 什麼是浮點數?
表示一個數字如100.2,可以是Fixed point也就是100.2,也可以是Floating point(也就是科學計數法scientific notation)1.002 × 102.
通常是以第一個非零數字作為小數點前的數,也被稱為normalized form,也就是說上麵的數字不會表示成100.2 ×
100
或0.1002 ×
103
浮點數的優點是能表示Fixed point無法表示的超大和超小數值
2. IEEE Standard 754
關於floating number在計算機中表示的定義。
Java中float(單精度浮點),double(雙精度浮點)也遵照次標準設計。
- The sign bit is 0 for positive, 1 for negative.
符號位0是正,1是負
- The
exponent(冪值)'s base is two. 冪值是2
- The
exponent field contains 127 plus the true exponent for single-precision(單精度),
or 1023 plus the true exponent for double precision(雙精度). - The
first bit of the mantissa is typically assumed to be 1.f, where f is
the field of fraction bits.
尾數中第一位任何情況下都是1(因為binary中隻有0,1),所以不用占空間,所以fraction bits都用來存儲.f
圖示如下:
float(32位):

double(64位):

3.為什麼會有精度丟失?
拿單精度浮點float為例,正常的整數integer,可以用全部32位表示數字,而Single Precision隻能有24位存儲數值,這24位是沒辦法
match 32位的精度的,所以就會丟失。例如:
11110000 11001100 10101010 00001111 // 32-bit integer
= +1.1110000 11001100 10101010 x 231 // Single-Precision Float
= 11110000 11001100 10101010 00000000 // Corresponding Value
4.如何解決?
通常會用long和BigDecimal來替代float,double。比如eBay內部的Money類,
就是用long來做internal value存儲amount的數值的。
就是用long來做internal value存儲amount的數值的。
5.Java考題常出現
當你不聲明的時候,默認小數都用double來表示,所以如果要用float的話,則應該在其後加上f
例如:float
a=1.3;
則會提示不能將double轉化成float 這是窄型轉化。
則會提示不能將double轉化成float 這是窄型轉化。
如果要用float來修飾的話,則應該使用float
a=1.3f
6.Java變量取值範圍
byte的取值範圍為-128~127,占用1個字節(-2的7次方到2的7次方-1) short的取值範圍為-32768~32767,占用2個字節(-2的15次方到2的15次方-1) int的取值範圍為(-2147483648~2147483647),占用4個字節(-2的31次方到2的31次方-1) long的取值範圍為(-9223372036854774808~9223372036854774807),占用8個字節(-2的63次方到2的63次方-1)float (單精度浮點)約等於(-1 x 2-127 ~ +1 x 2127),占4個字節(指數段8bits)
double(雙精度浮點)約等於(-1 x 2-1023 ~ +1 x 21023),占8個字節(指數段11bits)
最後更新:2017-04-02 06:52:08