我目前正在開發一個java程序,它需要向一個雙變量添加一個小的常量值,例如0.00000000001,例如。位置。但是,當我運行代碼時,對其進行調試,然後到達將0.00000000001添加到位置的位置,並在添加完成後檢查調試模式下的位置值。看來該位置沒有添加0.00000000001。例如,加入前的位置等於438.0,加入後的位置等於438.0。下面是簡單的代碼是什麼樣子在java中添加非常小的值
位置+ = 0.00000000001
任何想法一個例子嗎?提前致謝。
我目前正在開發一個java程序,它需要向一個雙變量添加一個小的常量值,例如0.00000000001,例如。位置。但是,當我運行代碼時,對其進行調試,然後到達將0.00000000001添加到位置的位置,並在添加完成後檢查調試模式下的位置值。看來該位置沒有添加0.00000000001。例如,加入前的位置等於438.0,加入後的位置等於438.0。下面是簡單的代碼是什麼樣子在java中添加非常小的值
位置+ = 0.00000000001
任何想法一個例子嗎?提前致謝。
由於存儲方式的緣故,許多double值在Java中並不準確。精確的精度僅適用於某些值。這是因爲Java只能將十進制值存儲爲多個2^n(s)的組合。
如:1/4
可以存儲爲2^-2
,但1/3
將存儲爲2^-2 + 2^-3+ 2^-4 +2^-5...
,所以1/3
是不完全準確的值的例子
如果你想有一個精確值,使用BigDecimal
類:
http://docs.oracle.com/javase/7/docs/api/java/math/BigDecimal.html
它們*精確,但它們沒有任意的精度,也不能精確地表示每個十進制數。 0.5的double值仍然恰好爲0.5。 –
是的,我明白這一點。編輯。 –
所以只是爲了澄清。雙打可以使用小數保持真正的大數,當他們變得非常小時,它們在處理小數時會遇到麻煩? – johns4ta
您需要使用BigDecimal更好的精度。
實施例:
BigDecimal test = new BigDecimal(438.0);
test = test.add(new BigDecimal(0.0000000000001));
System.out.println(test);
使用BigDecimal類。它具有任意的精度,並且能夠處理微小的值。
如果超出double
的精度,則添加一個非常小的值無效。
for (double d = 438; d < 1e7; d *= 10) {
double location = d;
location += 0.00000000001;
System.out.println(location);
}
打印
438.00000000001
4380.00000000001
43800.00000000001
438000.0
4380000.0
你可能運行到一個舍入誤差或下溢。我會嘗試使用BigDecimal進行任意精度。
你應該閱讀雖然http://firstclassthoughts.co.uk/java/traps/java_double_traps.html
這進入了Java商店和處理雙打和彩車,他們的意思是,當你使用,並比較他們什麼。
這是基本的情況下,「你看到的是不是你拿」
,如果你決定使用大十進制這有其自身的陷阱案件
http://firstclassthoughts.co.uk/java/traps/big_decimal_traps.html
這真的歸結爲什麼你想添加0.00000000001?
只需要使兩個值的差值儘可能小時,它們本來就是相等的,在我的算法中,在某些情況下它們並不等於防止被零除。這只是我希望稍後修復的一個快速解決方案,但尚未找到合適的解決方案。 – johns4ta
還有一件事要添加到另一個答案。問題不在於值太小。更大的價值=更大的不確定性。看一個例子:
float x = 20000000.0f;
for (int i = 0; i < 10000000; i++) {
x += 1;
}
System.out.println(x); // prints 20000000.0f, not 30000000.0f!
所以,如果你使用的循環浮點數你永遠無法退出這個循環
http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg。 html – NPE
什麼是位置類型? – David