zoukankan      html  css  js  c++  java
  • 计算机系统中的整数运算

    上一篇随笔中介绍了“计算机系统内的整数表示”,本文继续探索整数运算的本质。
     
    计算机系统内的整数运算的局限:
      表示整数的二进制位是一定的,所以表示的整数的范围是局限的。
    “整数”运算实际上是一种模运算:
      表示数字的有限字长限制了可能的取值范围,结果运算可能溢出,所以运算结果都是取模之后的。
     
     
    无符号加法
    一个算术运算溢出,是指完整的整数结果不能放到数据类型的字长限制中去。
    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),再执行算术右移,使结果正确舍入)

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

  • 相关阅读:
    HDU3145 Max Sum of Max-K-sub-sequence (单调队列模板)
    AcWing1088 旅行问题(单调队列)
    POJ1821 Fence(单调队列)
    POJ1742 Coins(多重背包+二进制优化)
    AcWing217 绿豆蛙的归宿(期望)
    BZOJ.2134.[国家集训队]单选错位(概率 递推)
    洛谷.3805.[模板]manacher算法
    Codeforces.280C.Game on Tree(期望)
    BZOJ.2521.[SHOI2010]最小生成树(最小割ISAP/Dinic)
    洛谷.4172.[WC2006]水管局长(LCT Kruskal)
  • 原文地址:https://www.cnblogs.com/windlaughing/p/2997910.html
Copyright © 2011-2022 走看看