兩個數的平均值是很是簡單的,也就是 (a+b)/2. 但具體到C語言環境裏,卻有玄機。git
對兩個Int32類型大數,例如2147483644和2147483646,求平均值。首先在C裏用嘗試如下算法:github
int a = INT32_MAX - 3; //2147483644 int b = INT32_MAX - 1; //2147483646 int val = (a + b) / 2; printf("average1: %d + %d = %d\n", a, b, val); //實際打印結果: //2147483646 + 2147483644 = -3
顯然結果非咱們指望的,這是由於 a+b之和超出了Int32的範圍。而對於-3的由來,咱們能夠以下推算:算法
假定INT32_MIN = -2147483648, INT32_MAX = 2147483647, 那麼:
INT32_MIN + INT32_MAX == -1
INT32_MIN == INT32_MAX + 1code
因此 a + b = INT32_MAX - 3 + INT32_MAX - 1get
= INT32_MIN - 1 - 3 + INT32_MAX - 1 = INT32_MIN + INT32_MAX - 5 = -1 - 5 = -6 (a+b)/2 = -6/2 =-3
如何求得正確的平均值呢?源碼
直接上代碼:it
int a = INT32_MAX - 3; //2147483644 int b = INT32_MAX - 1; //2147483646 if ((a >0 && b>0) || (a<0 && b<0)){ val = a + (b-a)/2; } else { val = (a+b)/2; } printf("average2: %d + %d = %d\n", a, b, val); //2147483646 + 2147483644 = 2147483645
主旨思想就是確保計算過程中,不要有超出int32範圍的中間數。ast
Short型運算時,會把Short型自動轉爲Int32型,因此基本上不用考慮溢出的問題了。語言
short x = INT16_MAX - 3; //32764 short y = INT16_MAX - 1; //32766 short val = (x + y) /2; printf("(%d + %d)/2 = %d\n", x, y, val); // (32766 + 32764)/2 = 32765
源碼上傳到:https://github.com/JackieGe/c...co