2016-03-02 125 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是有解决您的特殊问题。

请注意您的变量准确性并在它们之间进行转换。