因為十進位制運算的底層是2進製運算,有些浮點數並不能完全用二進位制表示,一定會有誤差,誤差在小數點最後幾位。
比如下面這個例子,想要分別取出整數部分和小數部分。浮點數26.90想要得到的理想輸出結果是 整數26和整數90 兩個數。
float value =
26.90
;unsigned
int value_integer;
//存放整數 26
unsigned
char value_decimal;
//存放小數(實際放大了100倍) 90
float decimal_old;
//存放小數(未乘以100)
float decimal_new;
//存放小數(乘以100)
value_integer =
(unsigned
int)value;
//取整數 26
decimal_old = value - value_integer;
//取小數(未乘以100)
decimal_new = decimal *
100.0f
;//取小數(乘以100)
value_decimal =
(unsigned
char
)decimal_new;
//強制型別轉換,取出小數部分 90
printf
("value = %d"
,value)
;printf
("value_integer = %d"
,value_integer)
;//列印整數部分
printf
("decimal_old = %f"
,decimal_old)
;//列印小數部分(未乘以100)
printf
("decimal_new = %f"
,decimal_new)
;//列印小數部分(乘以100)
printf
("value_decimal = %d"
,value_decimal)
;//列印左移兩位小數點後的小數部分,即實際放大了100倍
經過實驗**後,得到的輸出結果如下
value =
26.900000
value_integer =
26decimal_old =
0.900000
decimal_new =
89.999962
value_decimal =
89
會發現前後結果不一致,得不到理想的效果:整數26和整數90。因此,需要對浮點數進行一定的處理。
//函式功能:將浮點數分離成 整數部分和小數部分
//value:待分離的浮點數
//value_integer:指標,用於存放整數部分
//value_decimal:指標,用於存放小數部分
static
void
separate_integeranddecimal
(float value,
unsigned
int*value_integer,
unsigned
char
*value_decimal)
實驗**後得到理想的實驗結果,分離出整數26和整數90。
這裡特別注意:
浮點數計算一直計算下去,誤差會越大,所以value每次傳入的值都是新的(每次傳入乙個確定的實參浮點數)的話,不會有任何影響(一點都不會有)。
但是,如果一開始就定義乙個變數temp,並且temp一直自加乙個浮點數,再把temp作為引數多次傳進這個分離整數和小數的函式,那麼它的結果誤差會越來越大。
比如下面這個例子
float temp =
26.90f
;unsigned
int value_integer;
unsigned
char value_decimal;
while(1
)
浮點數的運算
規格化的浮點數因為儲存是使用類似科學計數法的表示,因此計算方法大體上與科學計數法較為類似。浮點加減法的一般步驟 減法本質也是加法 對於二進位制形式的兩個浮點數相加 1.對階 對於兩個規格化浮點數,將較小的指數的數向較大指數的數對齊。通過移動小數點實現。如果出現有效數字位數不能滿足的情況,進行近似。2...
浮點數運算出現誤差的解決方案
直接上 public static void main string args 輸出結果 4.4399999999999995 4.44使用bigdecimal承載資料的型別最好是string型別,否則依然會出現誤差 同時附上加減乘除的方法 public static void main strin...
浮點數運算的陷阱
浮點數的運算不能說是精確的,因為某些數字不能準確表示為二進位制 例如 0.1 以下是乙個用浮點數運算的例子,例子證明了我們應該慎用浮點數運算。author crane.ding public class test 執行結果如下 0.70000005 false 0.7000000238418579 ...