整数运算

无符号加法

当 x+y >= 2^w,实际结果为 s = x+y-2^w

x+y,s = (x+y) % 2^w

检验溢出的方式:如果 s<x,说明溢出

无符号数的非~x = 2^w - x (x>0)

~x=x(x=0)

补码加法

当 x+y >= 2^(w-1), s = x+y-2^w

当 x+y < -2^(w-1),s = x+y+2^w

正溢出的结果是负数,负溢出的结果是正数。

检验溢出的方式:当 x,y>0 而 s<=0 是正溢出;当 x,y<0 而 s>=0 是负溢出

补码的非

当 x = TMin,-x = TMin

当 x ≠ TMin,-x = -x

补码(Two’s Complement)是一种在计算机系统中表示有符号整数的方法。对于一个给定的二进制数,补码是通过以下步骤得到的:

  1. 取反:将所有的1变为0,所有的0变为1(除了最高位符号位)。
  2. 加一:将取反后的结果加1。

补码的非(Negative of a Complement)是指对一个数的补码再取补码。具体来说,一个数A的补码的非可以这样得到:

  1. 取反:将A的补码按位取反(包括符号位)。
  2. 加一:将取反后的结果加1。

补码非的位级表示:****对每一位求补,结果再加 1

计算补码非的第二种方法:假设 k 是最右边的 1 的位置,对 k 左边的所有位取反

无符号乘法

无符号乘法的积 m = (x*y) % 2^w

补码乘法

补码乘法的积 m = (x*y) % 2^w

乘以常数

大多数机器上,整数乘法需要 10 个或更多的时钟周期,而加法、减法、位级运算和移位只需要 1 个时钟周期

编译器对整数乘法进行优化的方式:用移位和加法或减法运算的组合来代替常数因子的乘法。

左移 k 位等于乘以 2^k

例: x*3= x<<2+x

除以2的幂

除以 2 的幂可以用移位运算来代替,无符号采用逻辑右移,补码采用算术右移

对于有符号数而言,算术右移的结果相当于进行除法运算后向下舍入

浮点数

非常大,非常接近零,近似值计算

二进制小数

小数的二进制表示法都是近似表示,x 可以由形如 2^i + 2^j + … + 2^n 的多项式表示

IEEE 浮点表示

IEEE 浮点标准的表示形式为:V = (-1)^S * M * 2^E

  1. 符号S 决定是负数还是正数
  2. 尾数M 是一个二进制小数,范围是 12-ε 或 01-ε
  3. 阶码E 的作用是对浮点数加权

不同精度的浮点的尾数和阶码也有所不同

  1. k 位的阶码字段 e编码 E;float 中 k=8,double 中 k=11
  2. n 位的小数字段 f 编码 M;float 中 n=23,double 中 n=52

被编码的值可以分成三种情况:

规格化的值:阶码字段即不全为 0 也不全为 1 时属于规格化值

  • 阶码字段解释方式:E = e - (2^(k-1)-1)

    小数字段解释方式:M = 1 + f

非规格化的值: 阶码字段全为 0 时属于非规格化形式

特殊值: 阶码字段全为 1

    1. 小数字段全为 0:表示无穷
    2. 小数字段非零:表示 NaN(not a number)

舍入

向偶数舍入(向最接近的值舍入):非中间值 (0.5) 四舍五入,中间值向偶数舍入。

向零舍入

向下舍入

向上舍入

浮点运算

IEEE 标准定义 1/-0 = -∞,1/+0 = +∞

浮点运算是可交换不可结合也不可分配

浮点加法满足加法和乘法上的单调性。如果 a>=b,则 x+a >= x+b

c语言中

int 到 float:不会溢出,可能舍入

int 或 float 到 double:不会溢出也不会舍入

double 到 float:可能溢出和舍入

float 或 double 到 int:向零舍入,很大时可能溢出,很接近零时也可能溢出。当从浮点转换到整数时如果溢出,转变结果都为 [1000],因此一个正浮点可能得到一个负整数