简体   繁体   中英

Error in Floating point operation in C

Please let me know the difference between the following C functions.

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;
}

And the following

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;
}

Please see my comments for the change in code.The function gives different values for some inputs. Is the float getting erred off due to combining the two statements?

In a mathematics the two statements would be equivalent. However in computer hardware they may not be.

You could be getting round off error because the initial result (new_re) is rounded and then added to c_re .

As Niklas mention:

intermediate values are stored with higher precision

so the result of new_re may lose some floating points when stored to new_re, but if the intermediate values are added to c_re then a small value of c_re combined with lower significant values of new_re calculation may contribute to the end result.

When evaluating a math expression the code generated by a C or C++ compiler is allowed to keep intermediate results with an higher precision.

For example on x86 computers C and C++ double values are normally 64-bits IEEE754 floating point numbers, but the math processor stack uses 80 bits per value when doing the computations.

This means that the exact result of a computation will depends on where a temporary is stored in memory and where it was instead kept on the fp stack. Normally this is not a problem because the precision of temporaries is higher than the precision of stored values... but this is not always true because the computation may have been designed exactly around the floating point expected rounding rules.

Note also that compilers provide special flags to ask to be strict about the math evaluation or to allow them to be very liberal to help optimizations (including ignoring storing operations into local variables or rewriting operations to theoretical math equivalent versions). The default today is often to be somewhat liberal and not very strict because that impairs performance.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM