-
Notifications
You must be signed in to change notification settings - Fork 13
coding_005
Zhang Jc edited this page Nov 28, 2018
·
2 revisions
C等编程语言中一般用补码表示有符号数。补码的意思就是计算时最高位权值为负。比如对于一个4字节的int,1000 0000 0000 0000
为最小的数,其绝对值为 2^31,表示-2^31。 最大的数为0111 1111 1111 1111
为2^31 - 1。
对于无符号数,扩展的高位补0,这明显不会改变数的大小。
对于有符号数,扩展的高位全部填充原始的符号位。这也不会改变数的大小:对于正数很好理解,符号位为0,和无符号数一样没有影响;对于负数,虽然新扩展的位全部为1,经过推算数的大小也是不变的。
对于位数的缩减的情况,则直接截断前边的若干位,这也相当于做了取模运算,这种可能导致这个数的大小发生改变,这也是溢出的一种情况。
-
若一个有符号数和一个无符号数进行运算,有符号的会被隐式地转为无符号的再进行预算。
-
两个不同类型数进行预算,位数小的会被隐式转为位数最大的数的类型。
-
赋值运算时,右值最终结果会被转为左值类型再付给左值。
乘法或加法、有符号或者无符号数都可能溢出,运算后相当于将值作截断处理,所以可能不是预期的结果。
-
对于无符号数,很显然,两个最大的正数相加后的结果需要多一位才能进行存储,所以肯定会导致溢出。
-
对于有符号数,由于补码的特性,其运算的机器指令和无符号数相同,但是由于第一位为符号位,产生正数变负数,负数变正数的溢出:
- 当两个较大正数相加时,符号位会被置1;
- 当两个绝对值较大负数相加时,符号位会被置0;
乘法和加法类似,也是算完后截取,也是有符号和无符号的机器指令相同,也有可能发生溢出情况。
[1] CSAPP chapter. 2
本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。
Wiki: wiki.jcix.top ~聚沙成塔~ Blog: blog.jcix.top