计算机系统中的整数运算

上一篇随笔中介绍了“计算机系统内的整数表示”,本文继续探索整数运算的本质。
 
计算机系统内的整数运算的局限:
  表示整数的二进制位是一定的,所以表示的整数的范围是局限的。
“整数”运算实际上是一种模运算:
  表示数字的有限字长限制了可能的取值范围,结果运算可能溢出,所以运算结果都是取模之后的。
 
 
无符号加法
一个算术运算溢出,是指完整的整数结果不能放到数据类型的字长限制中去。
C语言中真正执行的无符号加法:+uw  (用这种符号区别标准的加法; + 表示标准的加法),又称为 模数加法。
  
                  = (x+y)mod 2^w

 

整数加法和无符号加法间的关系。当x+y大于2w-1时,其和溢出。

 例如:(231 = 2147483648)

        unsigned int u1=2147483648u+2147483647u;
        printf("u1=%u\n",u1);
        unsigned int u2=2147483648u+2147483647u+1;
        printf("u2=%u\n",u2);

输出:u1=4294967295

     u2=0

 

补码加法
在计算机计算中,通常将表示截断到w位,来避免数据大小的不断扩张。C语言中真正执行的补码加法:+tw(用这种符号区别标准的加法)

 

 

整数和补码加法之间的关系:

当x+y小于-2w-1,产生负溢出。当它大于2w-1 -1时,产生正溢出。

例如:(int类型的最大正数为:231-1 = 2147483647)

        int y=2147483647+1;
        printf("y=%d",y);

输出:y=-2147483648 

 

补码的非运算

 

无符号乘法
其中 x*y指实数内的乘法。

有符号乘法

 

乘以常数
对于无符号和有符号变量x:C表达式 x<<k 等价于 x*2^k。 (左移运算)
(可以理解为:这是对二进制表示的运算,无符号和有符号是对二进制表示的两种解释)
例如:14=2^3+2^2+2  所以 x*14=(x<<3)+(x<<2)+(x<<1)
      或14=2^4-2  所以 x*14=(x<<4)-(x<<1)
         -6=2-8    所以  x*(-6)=(x<<1)-(x<<3)
 
 
除以2的幂
整数除法总是舍入到零,对于x>=0,y>0  ,结果是 (下取整),对于x<0,y>0,结果是(上取整)
 
对于无符号变量x:C表达式x/2^k等价于x>>k。(逻辑右移)
对于有符号变量(补码)x:表达式x/2^k等价于(x<0 ?  (x + (1<<k) -1)  : x ) >>k。(算术右移)
     (当x<0时,x上加上一个适当的偏移量(2^k-1),再执行算术右移,使结果正确舍入)

 

(转载请注明出处 ^.^)

posted @ 2013-04-03 14:44  windlaughing  阅读(2100)  评论(1编辑  收藏  举报