简体   繁体   中英

How can I get the best accurate result?

Given:

unsigned int a, b, c, d;

I want:

d = a * b / c;

and (a *b ) may overflow; also (b/c) may equal zero and give less accuracy.

Maybe a cast to 64-bits would get things to work, but I want to know the best way to get the most accurate result in d.

Is there any good solution?

I would either:

  • Cast to 64 bits, if that will work for your ranges of a, b, and c.
  • Use an infinite precision library like GMP
  • Cast to a float or double and back, if you find those results acceptable.

For best accuracy/precision you'll want to do your multiplies before your divides. As you imply, you'll want to use something with twice as many bits as an int:

int64_t d = (int64_t) a * (int64_t) b;
d /= c;

You don't need both casts, but they arguably make it a bit clearer.

Note that if c is small enough, then d can still be bigger than an int. That may or may not be an issue for you. If you're sure it isn't you can cast down to an int at the end.

使用浮点数或双精度数,在浮点运算中, 允许除以零 ,结果将为正无穷大

You can always do an explicit check for overflow on a * b:

long long e = (long long) a * (long long) b;
if (e <= INT_MAX) {
    d = e / c;
} else {
    d = a * (b / c);
}

Of course this only works for non-negative a, b, c. If they can be negative you'll also have to check against INT_MIN.

[Update] You could also check which of a and b is larger and thus loses less precision when divided by c:

if (a >= b) {
    d = a / c * b;
} else {
    d = a * (b / c);
}

For your problem as stated, I'd do d = (long long)a * b / c;

No sense in going to float when you only need more bits. No need to redeclare or cast everything. Casting a is enough to promote b and c to larger size in the expression.

I'd do something along the lines of the following:

if(c){
    d = (long long)a * b;
    d /= c;
}
else{
    // some error code because div by 0 is not allowed
}

Why not use a float or double ? A float (on intel chips) is a 32-bit floating-point number, so you wouldn't necessarily need 64 bits for the operation?

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