簡體   English   中英

C ++雙重除法和返回

[英]C++ double division and return

我了解雙打只是近似值。 但是我很驚訝

double f(int x, int y)
{
    return double(x)/y;
}

double f(int x, int y)
{
    double z = double(x)/y;
    return z;
}

可以返回不同的值。 有人知道為什么嗎?

“為什么”的主要原因是該標准允許它(但我不是100%肯定它會這樣做)。 務實的原因是,在某些處理器(包括Intel 32位處理器)上,浮點寄存器比double精度更高。 如果中間計算適合,則在寄存器中進行中間計算(標准明確允許中間結果具有更高的精度),因此任何給定表達式的結果將取決於編譯器如何管理其寄存器以及何時將其溢出到內存中。 並且許多(大多數?)此類處理器的編譯器將在寄存器中返回浮點值,從而保持了額外的精度。 (我不確定這是否合法。分配雙精度數時,我認為在復制構造雙精度數時,必須使值適合。返回值是復制結構,因此我認為應強制使雙精度數適合無論如何...大多數編譯器都不需要,所以不管標准可能要說什么,也不必說它。

我認為您可以通過顯式轉換最終結果來防止這種情況,即:

return double( double(x)/y );

,但我不確定(既不知道標准說了什么,也不知道編譯器實際上做了什么)。

請注意,結果是否不同取決於您對它們的處理方式。 如果立即將它們分配給double ,或將它們傳遞給需要double另一個函數,則所有發生的情況是舍入發生得稍晚一些(但仍使用相同的值)。 但是,如果您在表達式中使用該值,則所有選擇均無效。 在你的情況, 2.0 * f( a, b )可能會導致不同的值取決於你的實現f ,甚至四舍五入后。 最值得注意的是, f( a, b ) == f( a, b )可能返回false。 (我在哪里見過這引起了的情況下std::sort崩潰所使用的比較函數做線沿線的一些東西。 return lhs.f() < rhs.f(); ,並返回true時, lhsrhs是引用相同的對象;編譯器將調用的第一個函數的結果溢出到內存中,然后與第二個函數返回的寄存器中的值進行比較。)

我能想到的唯一方法是在x87 FPU上使用優化的編譯器。 x87 FPU使用長雙精度,因此與堆棧中雙精度變量的值相比,寄存器中的值可以保持更高的精度。 至少可以想象,給出上述代碼的優化編譯器可能在一種情況下使用寄存器作為返回值,而在另一種情況下使用堆棧。

但我想看到一個真實的例子。

我編寫了方法,並進行了簡單測試,將它們都調用。 這些值簡單地(就方面而言)相等。 這里有兩個選擇:1)您正在提出一個錯誤的問題。 [我不這么認為!] 2)當您將值“存儲”在z中時,編譯器將進行更多的隱式強制轉換,從而降低了變量的精度。 問題也可能是您傳遞值的方式。 實際上,在許多語言中,如果賦值得到.5 [EG float = .5],則除法[EG float z = 1 / 2; ]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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