整数在计算机内以有限字长表示,当超出最值(有限字长)时,需要截断(溢出,求模)操作。
最大的负整数是多少(最小的正整数是多少)
不同字长的整型具有不同的值域,混合运算时,需要类型提升和转换。
在
democode:
2.1无符号(unsigned)整数加法的溢出
w位(二进制位)无符号整数v在计算机中可以表示的值域为:
考虑两个非负整数x和y,满足,每个数都能表示为w位无符号整数。
然而,如果计算它们的和,我们就有一个可能的范围。表示这个和可能需要w+1位,对于有限字长的无符号整数加法,其多出的一位就会截断,也就是溢出或模的运算。
溢出检测:
2.2有符号(signed)整数(补码)加法的溢出
w位(二进制位)有符号整数v在计算机中可以表示的值域为:
w位(二进制位)有符号整数x+y的溢出情况:
溢出检测:
对于乘法,是一种特殊的加法。
对于除法,不存在溢出。
溢出也会改变标志寄存器的状态:
可以检测标志寄存器来判断是否溢出:
当较宽的整型赋值给一位较窄的整型时,需要截掉高位来赋值:
较大的longint,当截断后,可能会出现首位是1的情况时,其位数的值的位模式会被译码为一个负值:
不同数据类型在混合运算时,时常会进行整型提升或者强制转换的操作,C语言中提升规则如下图:
当有char、short、signedint的类型混合运算时,都会提升为signedint类型,并作为整体表达式的类型,如果需要赋值给左值,则表达式的类型会自动转换为左值类型。
当有char、short、signedint、unsignedint类型混合运算时,都会提升为unsignedint类型进行运算。
当有char、short、signedint、unsignedint、long类型混合运算时,都会提升为long类型进行运算。
当有char、short、signedint、unsignedint、long类型混合运算时,都会提升为long类型进行运算。
当整型与浮点数混合运算时,会提升为浮点型进行运算。
当无符号整形与有符号整型同时用在关系表达式时,有符号整型会提升为无符号整型,可能会出现令人意想不到的结果,有时就类错误很难排查。
如strlen()返回的就是一个unsignedint,让类型提升问题更具有隐藏性:
ref
发表评论