[英]c++ produces erroneous computation results. Can this be corrected?
我在“問Ubuntu”論壇上問了以下問題,並被告知該問題不適合該論壇。 有人建議我在這里問我的問題。 如果這不是該問題的合適場所,我提前致歉。
我目前使用Java作為默認語言。 另外,我當前正在運行Kubuntu版本12.04。 我正在將c ++程序轉換為java,而java程序的結果與c ++程序的結果不匹配。 當我意識到Java程序產生正確的結果而C ++程序產生不正確的結果時,我開始四處尋找問題。 我的問題是,有人可以解釋為什么c ++會產生錯誤的結果,並且可以解決該問題嗎?
我寫了兩個最小的程序來說明這個問題。 我還編寫了一個腳本文件來顯示兩個程序,然后編譯並運行它們。 結果如下。 顯然,有效數字在同一個鄰域中,但是當處理10的大數冪(例如30的冪)時,相差很大。 這是我的測試程序和腳本的結果:
Linux Pegasus 3.2.0-54-generic#82-Ubuntu SMP Tue Sep 10 20:08:42 UTC 2013 x86_64 x86_64 x86_64 GNU / Linux
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
double testValue;
//---------------------------------------------------------------------
testValue = 1.0e0 * 1.9891e30;
cout << scientific << showpoint << right << setprecision(20)
<< "The test value = "
<< setw(25) << testValue
<< " the test value should be 1.9891e30\n"
<< endl;
return 0;
}
class test
{
public static void main (String[] args)
{
double testValue;
//---------------------------------------------------------------------
testValue = 1.0e0 * 1.9891e30;
System.out.format
(
"The test value = %.20e the test value should be 1.9891e30%n", testValue
);
} // end main
}
測試值= 1.98909999999999988781e + 30測試值應為1.9891e30
測試值= 1.98910000000000000000e + 30測試值應為1.9891e30
顯然,由c ++程序產生的testValue值是錯誤的,而由Java程序產生的testValue值是正確的。 任何和所有對此問題的見解將不勝感激。 我已經搜索了google,並在此處使用搜索字詞“ c ++錯誤計算”,但沒有任何重大發現。
我不確定您如何看待這種計算錯誤? 浮點數學運算中的值存在細微的差異。 在具有單個編譯器的單個計算機上,浮點值是確定性的,但是,對於不同的語言和不同的編譯器,不能保證您得到相同的結果。
我的老教授布魯斯·道森(Bruce Dawson)給出了很好的概述: http : //randomascii.wordpress.com/2012/04/05/floating-point-complexities/ http://randomascii.wordpress.com/2013/07/16/floating-點確定性/
您在上面看到的結果對我來說還不錯。 也許您應該將小數點后的數字四舍五入到3位,然后用它來比較結果值。 使用浮點數時,您將很難在不同的語言和編譯器之間更精確地獲取浮點數。
另外,我建議下次使用“浮點數誤差”作為更好的Google搜索。
C ++代碼打印出實際值,而Java代碼則舍入該值。 請記住,數字0.0001
和0.1
不能完全用二進制表示。
您可以使用BigDecimal
獲取它來打印實際值,該實際值將與C ++輸出相同:
import java.math.*;
class test
{
public static void main (String[] args)
{
double testValue;
testValue = 1.0e0 * 1.9891e30;
BigDecimal realvalue = new BigDecimal(testValue);
System.out.format
(
"The test value = %.20e the test value should be 1.9891e30%n", realvalue
);
}
}
產量
測試值= 1.98909999999999988781e + 30測試值應為1.9891e30
AFAIK,C ++和Java中的double
都將具有相同的值,但是在將它們打印出來時,您會看到差異。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.