2014-02-18 48 views
3

誰能告訴我爲什麼第9行和第11行的計算似乎是相同的,會產生兩個不同的輸出。我知道它們之間的差異並不是那麼好,但我正在使用這些值與OpenGL繪製線條,差別很明顯。從看似相同的計算中獲取不同的輸出

#include <iostream> 
#include <cmath> 

int main() 
{ 
    int ypos=400; 

    /// Output: 410. 
    std::cout << 400+(sin((90*3.14159)/180)*10) << std::endl; 

    ypos=ypos+(sin((90*3.14159)/180)*10); 
    /// Output: 409. 
    std::cout << ypos << std::endl; 

    return 0; 
} 

回答

5

真正答案是某處大約409.9999999

這被輸出double和舍入到410因爲數學是所有內聯:

std::cout << 400+(sin((90*3.14159)/180)*10) << std::endl; 

因爲ypos被聲明爲int,雙值正在截短409(其被定義行爲從鑄造到doubleint)時:

ypos=ypos+(sin((90*3.14159)/180)*10); 

/// Output: 409. 
std::cout << ypos << std::endl; 

ñ OTE你可以還通過使用更好的常數PI提高精度:

const double PI = 3.141592653589793238463; 

std::cout << 400+(sin((90*PI)/180)*10) << std::endl; 

,但我還是會的結果存儲在double,而不是一個int以避免截斷。如果您需要整數結果,那麼我會第一輪:

ypos += round(sin((90*PI)/180)*10); 
+0

謝謝你的回覆。 – Aluthren

6

這是輸出一個浮點數

std::cout << 400+(sin((90*3.14159)/180)*10) << std::endl; 

但這輸出一個整數,所以將被截斷

std::cout << ypos << std::endl; 
3

這是GCC's most common non bug

這就是浮動的行爲實例。由於四捨五入錯誤,你不會得到一個確切的結果。它非常接近410,例如409.99999923。但是,如果將其作爲浮點數打印,默認情況下C++會舍入爲6位數,因此會給您410。第二次,您將其分配給整數。在這種情況下,C++不執行取整取整,而是執行截斷。這就是爲什麼要使用409.

+0

謝謝你的回覆。 – Aluthren

1

爲了保持代碼穩定,以便OpenGL輸出很好地運行,您應該儘可能使用雙精度(或儘可能)執行計算,以便截斷效果不會累積,並且最終在那裏我假設你需要一個整數像素數)或者總是舍入來生成一個整數值或截斷,但不能混合這兩個。

+0

感謝您的建議。 – Aluthren

相關問題