What is the right way to find the average of two values?

后端 未结 8 1140
北荒
北荒 2021-02-19 00:58

I recently learned that integer overflow is an undefined behavior in C (side question - is it also UB in C++?)

Often in C programming you need to find the average of two

相关标签:
8条回答
  • 2021-02-19 01:22
    (a >> 1) + (b >> 1) + (((a & 1) + (b & 1)) >> 1)
    

    The shift statement (x >> i) in c int mathematics is equivalent to a division by 2 to the power of i. So the statement (a >> 1) + (b >> 1) is the same as a/2 + b/2. However the mean of the truncated parts of the number need to be added as well. This value can be obtained by masking (a & 1), adding ((a & 1) + (b & 1)) and dividing (((a & 1) + (b & 1)) >> 1). The mean becomes (a >> 1) + (b >> 1) + (((a & 1) + (b & 1)) >> 1)

    Note: the reason to use >> and & rather than / and % as the division and remainder operators is one of efficiency.

    0 讨论(0)
  • 2021-02-19 01:24

    A simple approach is the following

    int c = a / 2 + ( b + a % 2 ) / 2;
    

    For example a and b can be represented as

    a = 2 * n + r1;
    b = 2 * m + r2;
    

    Then

    ( a + b ) / 2 => ( 2 * n + r1 + 2 * m + r2 ) / 2 => 2 * n / 2 + ( b + r1 ) / 2
    

    And the last expression gives you

    => a / 2 + ( b + a % 2 ) / 2
    

    The more correct expression is the following

    int c = a / 2 + b / 2 + ( a % 2 + b % 2 ) / 2;
    

    For example if we have

    int a = INT_MAX;
    int b = INT_MAX;
    

    then c calculated as

    int c = a / 2 + b / 2 + ( a % 2 + b % 2 ) / 2;
    

    will give c == INT_MAX

    EDIT: there was found interesting difference between the effect of computer operators and the effect of mathematical operators. For example according to the mathematics -1 can be represented as

    -1 = -1 * 2 + 1 
    

    that is according to the formula

    a = 2 * n + r1
    

    2 * n shall be an integer number less than or equal tp a

    So the number that is less -1 is -2. :)

    I think that the general formula shown by me would work it is required that for odd negative numbers there would be considered even negative numbers that less than the odd negative number.

    it seems that the correct formula looks as

    int c = ( a < 0 ? a & ~1 : a ) / 2 + 
            ( b < 0 ? b & ~1 : b ) / 2 + 
            ( ( a & 1 ) + ( b & 1 ) ) / 2;
    

    It is important to note that from the mathematical point of view the average of -1 and -2 shall be equal to -2 and the formula gives the correct result.:)

    0 讨论(0)
提交回复
热议问题