问题
Given long long x
, long long y
, and int z
, how can trunc((x
+y
+z
)/3) be calculated using fully defined operations in C but excluding unsigned long long
and wider arithmetic?
(trunc(x) is “rounding toward zero”: It is x if x is an integer and otherwise is the next integer toward zero.)
回答1:
You can calculate the average of two integers x
and y
without the risk of overflow as follows (pseudocode):
int average = (x and y have the same sign)
? x + (y - x) / 2
: (x + y) / 2;
This is not symmetric due to integer truncation. If you want to always round towards 0, you need to do something slightly more complicated:
int average = (x and y have the same sign)
? (x and y are both even or both odd)
? x + (y - x) / 2
: x + (y - x - sgn(x)) / 2
: (x + y) / 2;
where sgn
is the signum function (-1, 0, or +1 depending on whether the argument is negative, zero, or positive). There are lots of implementations of sgn(x)
, but one nice one is: (x > 0) - (x < 0)
.
If you want to always round down...that's left as an exercise. :)
回答2:
To average two unsigned numbers in C, you can use the fact that (L + R)/2 = L + (R-L)/2. Using the form on the right hand side guarantees the arithmetic will not overflow.
来源:https://stackoverflow.com/questions/64546414/math-operations-with-long-long-in-c