1

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.)

Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312
  • @EricPostpischil Unfortunately i cannot use it – deniskalistrat Oct 26 '20 at 23:45
  • 2
    @deniskalistrat: You need to specify the entire problem in the problem statement. – Eric Postpischil Oct 26 '20 at 23:53
  • @EricPostpischil Imagine that i need to find the avg of three numbers (two of them will be long long and one will be just normal int), how can I calculate it properly in c, assuming that i cannot use anything bigger than long long type? – deniskalistrat Oct 27 '20 at 00:15
  • @deniskalistrat: Is the updated problem statement I wrote correct and complete? It says fractions are rounded toward zero. Does it matter in which directions fractions are rounded? Could they be to-nearest or always down (toward −∞, same as floor(x)), or does it matter? – Eric Postpischil Oct 27 '20 at 00:20
  • 2
    duplicate: [Average of 3 long integers](https://stackoverflow.com/q/23949785/995714) – phuclv Oct 27 '20 at 00:24
  • For 2 `long long`, perhaps [Take the average of two signed numbers](https://stackoverflow.com/a/29834136/2410359) – chux - Reinstate Monica Oct 27 '20 at 00:51
  • Vote to reopen is premature until OP confirms the edit is correct and complete. – Eric Postpischil Oct 27 '20 at 02:28

2 Answers2

3

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. :)

Ted Hopp
  • 232,168
  • 48
  • 399
  • 521
0

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.

steeps
  • 65
  • 6