2016-03-02 315 views
3

我正在試驗C++。我寫了一個簡單的函數,它使用非常大的數字來查找三角形的面積。C++使用長雙精度使用雙精度

我將兩個大數字傳入函數,並從一個單獨的函數getValue()我從一個不同的方程返回一個單獨的值。我很好奇,爲什麼當我把1對括號外的線路,像這樣:

return (long long)(a - b/2.0) + b + 1; 

我得到的值9007200509008001

當我把1括號內,像這樣:

return (long long)(a - b/2.0 + 1) + b; 

我得到9007200509008000

第二值比第一少一個,即使計算應導致相同的答案。

#include <iostream> 

double triangleArea(int b, int h) 
{ 
    long long bh = (long long)b * h; 
    return 0.5 * bh; 
} 

long long getValue() 
{ 
    int deltaY = 18014400; 
    int deltaX = 1000000000; 

    long b = deltaY + deltaX + 1600; 
    double a = triangleArea(deltaX, deltaY); 
    return (long long)(a - b/2.0) + b + 1; 
} 

int main(int argc, char **argv) 
{ 
    std::cout << getValue() << std::endl; 
} 

我確定答案對某些人來說可能是顯而易見的,但是我無法把頭繞在它身上。有人可以解釋嗎?

+0

它的所有關於雙精度和表示。當處理非常大的雙打時,你可以添加一些不能改變的值,比如在這種情況下添加小號碼。當1個外括號中有很長時間沒有遇到這種麻煩 – vlad1slav

+0

由於您總是試圖獲取整數值,因此它不會建議使用double值,因爲它會失去精度。你可以這樣寫:'return static_cast (a) - (b/2)+ 1 + b;' – Mine

回答

6

當您除以2.0時,您將隱式轉換爲double。雙精度限制在十五位左右。那麼數字的數字是完全定義的,但可能並不是您所期望的。

如果您需要準確性,請嘗試使用long longunsigned long long並仔細控制您沒有溢出。如果還不夠,則必須使用多精度算術(例如GMP)。因爲一旦你使用雙浮點數,你的精度被限制爲53個二進制數字,或者大約15-16個十進制數字。

-1

long long通常具有更高的精度,即double。例如,如果兩者都是64位,則long long具有64位的精度,但double僅具有53位精度(52位尾數,隱含msb = 1)。

在你的情況,這是什麼意思是,a - b/2.0 + 1相同double常數a - b/2.0,但(long long)(a - b/2.0) + b + 1是不一樣的long long常數(long long)(a - b/2.0) + b

0

問題是在您的分區和變量a中隱式轉換的倍數。

看看下面的樣品間隙:

#include <iostream> 

double triangleArea(int b, int h) 
{ 
    long long bh = (long long)b * h; 
    return 0.5 * bh; 
} 

long long getValue() 
{ 
    int deltaY = 18014400; 
    int deltaX = 1000000000; 

    long b = deltaY + deltaX + 1600; 
    double a = triangleArea(deltaX, deltaY); 

    long long c = b/2.0; 

    long long d1 = a - c; 
    long long d2 = ((long long)a) - c + 1; 

    long long e1 = d1 + b + 1; 
    long long e2 = d2 + b; 

    return e1; 
} 

int main(int argc, char **argv) 
{ 
    std::cout << getValue() << std::endl; 
} 

的顯式的long long是有解決您的特殊問題。

請注意您的變量準確性並在它們之間進行轉換。