ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

北邮CSAPP第二章之整数运算

2020-12-17 21:58:36  阅读:285  来源: 互联网

标签:舍入 CSAPP 运算 符号 北邮 补码 第二章 溢出 乘法


整数运算

无符号加法

  • 两个非负整数的加法很有可能会导致溢出

  • 两数相加后,丢弃超越范围的数字,得到的结果类似于模运算

  • 例如9 + 12 = .21 = [10101] => [0101] = 5 = 21 % 16

  • 丢弃最高位相当于从和中减去2^w(无符号)

  • C语言不会因为溢出而发出信号

  • 检测溢出的方法:s = x + y(截取后), 若s < x或s < y,则发生了溢出

  • (不是很理解)阿贝尔群:对于无符号数,必有y使得x + y = 0(均限定在一定字节内),则y = (x = 0) => x; (x > 0) => 2^w - x

  • (x + y) - x总能求到y,与是否溢出无关

补码加法

  • 使用截断的方法避免数据大小的不断扩张

  • 正溢出,则结果为负数

  • 负溢出,则结果为正数
    x + y = {
    x + y − 2 w 正 溢 出 x + y - 2^w 正溢出 x+y−2w正溢出
    x + y 正 常 x + y 正常 x+y正常
    x + y + 2 w 负 溢 出 x + y + 2^w 负溢出 x+y+2w负溢出
    }

  • 大部分机器使用一模一样的指令执行无符号或者有符号的加法

  • 将参数转换为无符号数,执行无符号数加法,再转化为补码
    x + y = U2Tw[(x + y) mod 2^w]

  • 检测补码加法溢出方法
    s = x + y s = x + y s=x+y
    x > 0 && y > 0 && s <= 0 => 正溢出
    x < 0 && y < 0 && s >= 0 => 负溢出

  • 总结:x、y同号且不等于0时,s == 0,或s与x、y任意异号,则溢出

补码的非

  • TMin <= x <= TMax中,x的非:
    {
    x = T M i n = > T M i n x = TMin => TMin x=TMin=>TMin
    x > T M i n = > − x x > TMin => -x x>TMin=>−x
    }

  • 对w位的补码加法,TMin是加法的逆

  • 其它任意数值的x,都有-x作为加法的逆(整数非)

  • 补码非的位级表示

  1. − x =   x + 1 -x = ~x + 1 −x= x+1
  2. k:最右边的1的位置,则将前k位取反也可得到结果

无符号乘法

  • 将一个无符号数截断为w位等价于计算该值模2^w
  • 无符号乘法:
    x ⋅ y ( 无 符 号 乘 法 ) = ( x ⋅ y ) m o d 2 w x · y(无符号乘法) = (x · y)mod 2^w x⋅y(无符号乘法)=(x⋅y)mod2w

补码乘法

  • x ⋅ y = U 2 T w ( ( x ⋅ y ) m o d 2 w ) x · y = U2Tw((x · y)mod 2^w) x⋅y=U2Tw((x⋅y)mod2w)

  • 对于无符号与补码乘法来说,乘法运算的位级表示都是一样的

  • 对malloc进行乘法溢出验证
    malloc(ele_cnt * ele_size)
    ele_cnt * ele_size过大时,将溢出,例如
    ( 2 20 + 1 ) × 2 12 = 4096 ( 32 位 机 器 ) (2^{20} + 1) × 2^{12} = 4096(32位机器) (220+1)×212=4096(32位机器)

乘以常数

  • 整数乘法相当慢(比起其它指令)(包括移位)

  • 优化:使用移位和加法运算的组合来代替乘以常数因子的乘法

  • 也就是说,先考虑乘以2的情况,再概括成乘以任意常数

  • x < < k < = > x ⋅ 2 k x << k <=> x · 2^k x<<k<=>x⋅2k

  • 无论是通过无符号运算还是补码运算,乘以2的幂都可能导致溢出

  • 因为乘法的代价太大,因此编译器会将乘法指令重写为加法与移位混合的运算

  • 形式A: ( x < < n ) + ( x < < ( n − 1 ) ) + . . . + ( x < < m ) (x << n) + (x << (n - 1)) + ... + (x << m) (x<<n)+(x<<(n−1))+...+(x<<m)

  • 形式B: ( x < < ( n + 1 ) ) − ( x < < m ) (x << (n + 1)) - (x << m) (x<<(n+1))−(x<<m)(连续的1)
    y = 2 n + 2 ( n − 1 ) + . . . + 2 m = 2 ( n + 1 ) − 2 m y = 2^n + 2 ^ {(n - 1)} + ... + 2^m = 2^{(n + 1)} - 2^m y=2n+2(n−1)+...+2m=2(n+1)−2m

除以2的幂

  • 在大多数机器上,整数除法比整数乘法更慢:需要大概30个时钟周期

  • 初以2的幂也可以使用移位运算实现(右移):x >> k => x / 2^k

  • 整数除法总是舍入到0向下舍入一个正值,向上舍入一个负值

  • 对无符号整数使用移位:一定是逻辑移位

  • 移位总是舍入到0的结果

  • 无符号整数除法: x = 2 k x ′ + x ′ ′ x = 2^kx' + x'' x=2kx′+x′′, x ′ ′ x'' x′′为低k位的无符号数, x ′ x' x′为高w-k位的无符号数

  • x’ = x >> k

  • 补码运算的除法

  1. 执行算术右移
  2. x > = 0 x >= 0 x>=0时,效果与逻辑右移一致
  3. x < 0 x < 0 x<0时,再舍入时将导致向下舍入,因此需要修改策略
  4. x’:高w-k位的补码数,x’’:低k位的无符号数, x = 2 k x ′ + x ′ ′ x = 2^kx' + x'' x=2kx′+x′′
  5. 由4,x’ = x / 2^k向下取整,当为负数时不符合
  6. 通过增加偏置量来使其输出正确结果
  7. 结果: x / 2 k = ( x + ( 1 < < k ) − 1 ) > > k x / 2^k = (x + (1 << k) - 1) >> k x/2k=(x+(1<<k)−1)>>k(结果向上取整)
  8. 对于不需要舍入的情况,偏置量只影响将被舍入的低位;对于需要舍入的情况,将给高位加1,结果将向0舍入
  9. 补码运算的除法: ( x < 0 ? x + ( 1 < < k ) − 1 : x ) > > k (x < 0 ? x + (1 << k) - 1 : x) >> k (x<0?x+(1<<k)−1:x)>>k
  10. 利用的数学性质: x / y ( 向 下 取 整 ) = ( x + y − 1 ) / y ( 向 上 取 整 ) x / y(向下取整) = (x + y - 1) / y(向上取整) x/y(向下取整)=(x+y−1)/y(向上取整)
  • 不能使用除以2的幂的除法代替除以任意常数的除法

整数运算最后的思考

  • 计算机的整数运算实质上只是一种模运算形式
  • 补码提供了一种既能表示负数也能表示正数的灵活方法
  • 无论运算数是以无符号还是补码的形式表示的,它们都有完全一样或者非常类似的位级行为

标签:舍入,CSAPP,运算,符号,北邮,补码,第二章,溢出,乘法
来源: https://blog.csdn.net/weixin_45206746/article/details/111341138

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有