簡體   English   中英

C ++會產生錯誤的計算結果。 這可以糾正嗎?

[英]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

C ++源

#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;
}

Java源

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
}

g ++測試

測試值= 1.98909999999999988781e + 30測試值應為1.9891e30

Java測試

測試值= 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.00010.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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM