如果sizeof(int) = 4,那么下面的代码的结果是什么?
int x=255; printf ( "%d" , x>>34); |
实际输出:63
在编译这个代码时,编译器会给出警告
[Warning] right shift count >= width of type [enabled by default ] |
(这时假设位移运算位移步数只能在[0, type_bit_width)范围内)位移操作会对其位移步数对数值位宽(这里int类型为32位)做一次求余操作即上述代码等同于
x >> (34 % 32) |
实际上上述的等同不完全正确,当位移步数是负数时
x >> -1 // 0 |
这时通过%操作不能把位移步数转化到[0, type_bit_width)范围内(-1 % 32 = -1)
更为正确的我们可以用以下代码来等效
x >> remainder(-1, 32) |
remainder(match.h)函数和%虽然在正数范围内表现一致,但是在负数上有差异(确切的说是除数和被除数异号时)
取余围绕一下公式进行
q * b + r = a |
其中q = [a / b],r为余数。
但当a / b为一个浮点数时,它向那个方向取整决定了余数r的取值
这也就是为什么当除数和被除数异号(且a/b不为整数)时两者结果会有所不同,下面给出一个比较代码
for (int i=-15; i<16; i++) { if (i == 0) continue; printf("(%2d, %d)\n", i, 3); printf("%% : q = % d, r = % d \n", i / 3, i % 3); int q; double r = remainder(i, 3); printf("remainder: q = % d, r = % g\n", (i-(int)r)/3, r); }
运行结果:
(-15, 3) % : q = -5, r = 0 remainder: q = -5, r = -0 (-14, 3) % : q = -4, r = -2 remainder: q = -5, r = 1 (-13, 3) % : q = -4, r = -1 remainder: q = -4, r = -1 (-12, 3) % : q = -4, r = 0 remainder: q = -4, r = -0 (-11, 3) % : q = -3, r = -2 remainder: q = -4, r = 1 (-10, 3) % : q = -3, r = -1 remainder: q = -3, r = -1 (-9, 3) % : q = -3, r = 0 remainder: q = -3, r = -0 (-8, 3) % : q = -2, r = -2 remainder: q = -3, r = 1 (-7, 3) % : q = -2, r = -1 remainder: q = -2, r = -1 (-6, 3) % : q = -2, r = 0 remainder: q = -2, r = -0 (-5, 3) % : q = -1, r = -2 remainder: q = -2, r = 1 (-4, 3) % : q = -1, r = -1 remainder: q = -1, r = -1 (-3, 3) % : q = -1, r = 0 remainder: q = -1, r = -0 (-2, 3) % : q = 0, r = -2 remainder: q = -1, r = 1 (-1, 3) % : q = 0, r = -1 remainder: q = 0, r = -1 ( 1, 3) % : q = 0, r = 1 remainder: q = 0, r = 1 ( 2, 3) % : q = 0, r = 2 remainder: q = 1, r = -1 ( 3, 3) % : q = 1, r = 0 remainder: q = 1, r = 0 ( 4, 3) % : q = 1, r = 1 remainder: q = 1, r = 1 ( 5, 3) % : q = 1, r = 2 remainder: q = 2, r = -1 ( 6, 3) % : q = 2, r = 0 remainder: q = 2, r = 0 ( 7, 3) % : q = 2, r = 1 remainder: q = 2, r = 1 ( 8, 3) % : q = 2, r = 2 remainder: q = 3, r = -1 ( 9, 3) % : q = 3, r = 0 remainder: q = 3, r = 0 (10, 3) % : q = 3, r = 1 remainder: q = 3, r = 1 (11, 3) % : q = 3, r = 2 remainder: q = 4, r = -1 (12, 3) % : q = 4, r = 0 remainder: q = 4, r = 0 (13, 3) % : q = 4, r = 1 remainder: q = 4, r = 1 (14, 3) % : q = 4, r = 2 remainder: q = 5, r = -1 (15, 3) % : q = 5, r = 0 remainder: q = 5, r = 0 |
参考:
http://www.cplusplus.com/reference/cmath/remainder/
C traps & pitfalls
原文:http://www.cnblogs.com/lailailai/p/3661981.html