Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/163.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C中浮点运算出错_C++_C_Floating Point_Floating Accuracy - Fatal编程技术网

C++ C中浮点运算出错

C++ C中浮点运算出错,c++,c,floating-point,floating-accuracy,C++,C,Floating Point,Floating Accuracy,请让我知道以下C函数之间的区别 static int mandel(float c_re, float c_im, int count) { float z_re = c_re, z_im = c_im; int i; for (i = 0; i < count; ++i) { if (z_re * z_re + z_im * z_im > 4.f) break; float new_re = z_re

请让我知道以下C函数之间的区别

static int mandel(float c_re, float c_im, int count) {
    float z_re = c_re, z_im = c_im;
    int i;
    for (i = 0; i < count; ++i) {
        if (z_re * z_re + z_im * z_im > 4.f)
            break;

        float new_re = z_re*z_re - z_im*z_im;
        float new_im = 2.f * z_re * z_im;
        z_re = c_re + new_re;
        z_im = c_im + new_im;
    }

    return i;
}
static int mandel(浮点c_re,浮点c_im,整数计数){
浮动z_re=c_re,z_im=c_im;
int i;
对于(i=0;i4.f)
打破
浮动new_re=z_re*z_re-z_im*z_im;
float new_im=2.f*z_re*z_im;
z_re=c_re+新_re;
z_im=c_im+新im;
}
返回i;
}
以及以下

static int mandel(float c_re, float c_im, int count) {
    float z_re = c_re, z_im = c_im;
    int i;
    for (i = 0; i < count; ++i) {
        if (z_re * z_re + z_im * z_im > 4.f)
            break;

        float new_im = 2.f * z_re * z_im;
        z_re = c_re + z_re*z_re - z_im*z_im;//I have combined the statements here and removed float new_re
        z_im = c_im + new_im;
    }

    return i;
}
static int mandel(浮点c_re,浮点c_im,整数计数){
浮动z_re=c_re,z_im=c_im;
int i;
对于(i=0;i4.f)
打破
float new_im=2.f*z_re*z_im;
z_re=c_re+z_re*z_re-z_im*z_im;//我组合了这里的语句并删除了float new_re
z_im=c_im+新im;
}
返回i;
}

有关代码的更改,请参见我的注释。该函数为某些输入提供了不同的值。浮点数是否因为合并了这两个语句而出错?

在数学中,这两个语句是等价的。然而,在计算机硬件中,它们可能不是

您可能会得到舍入错误,因为初始结果(new_re)被舍入,然后添加到c_re

正如Niklas提到的:

中间值的存储精度更高


因此,new_re的结果在存储到new_re时可能会丢失一些浮点,但是如果将中间值加入到CYRE中,则CYRE的小值与新的较低的计算值结合可以有助于最终结果。

< P>在计算数学表达式时,允许由C或C++编译器生成的代码保持中间结果的精度较高。 <例如,在x86计算机C和C++ >代码>双< /COD>值通常是浮点数,但是在计算时,数学处理器栈每值使用80位。 这意味着计算的确切结果将取决于临时数据存储在内存中的位置以及它在fp堆栈中的保存位置。通常这不是问题,因为临时值的精度比存储值的精度高。。。但这并不总是正确的,因为计算可能完全围绕浮点期望的舍入规则进行设计


还要注意的是,编译器提供了特殊的标志,要求严格执行数学计算,或允许它们非常自由地帮助优化(包括忽略将操作存储到局部变量中,或将操作重写为理论数学等效版本)。今天的默认做法通常是有些自由而不是很严格,因为这会影响绩效。

你好,leon,我非常感谢你的努力。请举例说明。正确,由于中间值的存储精度更高,因此组合中的舍入误差更小。谢谢Niklas和leon!!这确实很有帮助。@anup.stackoverflow:对于x86处理器和代码生成器,
float
以24个有效位的精度存储,但是表达式
c_re+z_re*z_re-z_im*z_im
是以64位的精度计算的,它是四舍五入的(或者可能是截断的)当它被分配给变量时为24位。@wallyk:对于某些x86处理器和编译器,这是正确的,但肯定不是所有的。如果您能为“某些输入”提供不同的值,那就太好了。可以肯定的是,在IEEE754浮点运算中,运算不是关联的,即(a+b)+c!=a+(b+c)。例如,0.1+0.2-0.3=>5.551115123125783e-17,但0.1+(0.2-0.3)=>2.7755575615628914e-17