简体   繁体   中英

How to improve the precision of the result due to the lack of precision in C++ division

I am working on the leibniz question as indicated https://www.hackerrank.com/challenges/leibniz here. which computes 1-1/3+1/5-1/7+1/9+... Each element in the sequence can be defined as a(i)=(-1)^i/(2*i+1) start i from 0.

The question requires that to add from the first term to the nth term and output the result. My program passes the basic test cases. But it fails in other cases.

I guess my program fault is due to the precision when the number is large enough.

Can anybody provide a way to improve the precision of the result?

double leibnitz(int n) {
    double res = 0.0;
    for (int i = 1; i <= n; i++) {
        res += 1.0 / (2 * i - 1) * (i % 2 == 1 ? 1.0 : -1.0);
    }
    return res;
}

Start the loop with n and count down.

The reason is that small numbers around 0 can be added with higher precision because leading zeroes will be represented in the exponent part of the floating point number (hence the name "floating point"), making more of the mantissa available. So you may be able to approach 1 with a more precise sum of the smaller parts.

The loop should look like this:

for (int i = n; i >= 1; i--) {
    res += 1.0 / (2 * i - 1) * (i % 2 == 1 ? 1.0 : -1.0);
}

Jsfiddle with a simpler problem to illustrate that ordering may make a difference here:

http://jsfiddle.net/smt56/1

BTW: You should be able to shorten the expression to

res += ((i % 2) * 2 - 1) / (2.0 * i - 1)

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