如果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 = 0remainder: q = -5, r = -0(-14, 3)% : q = -4, r = -2remainder: q = -5, r = 1(-13, 3)% : q = -4, r = -1remainder: q = -4, r = -1(-12, 3)% : q = -4, r = 0remainder: q = -4, r = -0(-11, 3)% : q = -3, r = -2remainder: q = -4, r = 1(-10, 3)% : q = -3, r = -1remainder: q = -3, r = -1(-9, 3)% : q = -3, r = 0remainder: q = -3, r = -0(-8, 3)% : q = -2, r = -2remainder: q = -3, r = 1(-7, 3)% : q = -2, r = -1remainder: q = -2, r = -1(-6, 3)% : q = -2, r = 0remainder: q = -2, r = -0(-5, 3)% : q = -1, r = -2remainder: q = -2, r = 1(-4, 3)% : q = -1, r = -1remainder: q = -1, r = -1(-3, 3)% : q = -1, r = 0remainder: q = -1, r = -0(-2, 3)% : q = 0, r = -2remainder: q = -1, r = 1(-1, 3)% : q = 0, r = -1remainder: q = 0, r = -1( 1, 3)% : q = 0, r = 1remainder: q = 0, r = 1( 2, 3)% : q = 0, r = 2remainder: q = 1, r = -1( 3, 3)% : q = 1, r = 0remainder: q = 1, r = 0( 4, 3)% : q = 1, r = 1remainder: q = 1, r = 1( 5, 3)% : q = 1, r = 2remainder: q = 2, r = -1( 6, 3)% : q = 2, r = 0remainder: q = 2, r = 0( 7, 3)% : q = 2, r = 1remainder: q = 2, r = 1( 8, 3)% : q = 2, r = 2remainder: q = 3, r = -1( 9, 3)% : q = 3, r = 0remainder: q = 3, r = 0(10, 3)% : q = 3, r = 1remainder: q = 3, r = 1(11, 3)% : q = 3, r = 2remainder: q = 4, r = -1(12, 3)% : q = 4, r = 0remainder: q = 4, r = 0(13, 3)% : q = 4, r = 1remainder: q = 4, r = 1(14, 3)% : q = 4, r = 2remainder: q = 5, r = -1(15, 3)% : q = 5, r = 0remainder: q = 5, r = 0 |
参考:
http://www.cplusplus.com/reference/cmath/remainder/
C traps & pitfalls
原文:http://www.cnblogs.com/lailailai/p/3661981.html