有符号和无符号数回绕问题(补码加法和补码减法)
2013-08-04 02:22 youxin 阅读(3384) 评论(0) 编辑 收藏 举报我们知道,在有符号数中,最小值-1=最大值,最大值-1=最小值。我们称之为回绕wrap around。现在来说一般建议避免,因为其他架构的CPU,发生整数溢出时可能会触发CPU异常。
无符号最大值+1=0.
可见,无符号和有符号都会回绕。
为什么最小值-1=最大值。这要从计算机内部数字表示形式开始,都是采用补码表示。
补码表示有一些好处,统一了0([0]补=0000;).把减法都可以转换为加法。
补码加法:
[x]补+[y]补=[x+y]补 (mod 2^(n+1))(证明略)。
例:x=+1011;y=-0101;求x+y;
解:[x]补=01011;[y】补=11011;
[x]补 01011
[y]补 11011
===========
[x+y]补 (进位1丢掉)00110
结果为x+y=+0110;
补码加法的特点:1是符号位要作为数的一部分参与运算,而是要在模2^(n+1)的意义下相加,即超过2^(n+1)要丢掉。
补码运算符号位要参与运算。
(我们前面说的无符号最大值+1=0.可以这样理解,假设为 unsigned char
a=0xff; a+1 0xff+0x01=0x00(前面的进位丢掉了)。
更深入参考:http://zh.wikipedia.org/wiki/%E8%A1%A5%E7%A0%81
补码减法
负数的加法要利用补码转为加法来做。
【x-y]补=[x]补-[y]补=[x]补+[-y]补 ( -[y】补=[-y]补)
例:
x=+1101;y=+0110;求x-y;
[x]补=01101;
[y]补=00110;
[-y]补=11010;
[x]补 01101
[-y]补 11010
===========
(进位 1)00111
所以x+y=+0111;
溢出概念与检测方法:
在定点机器中,数的表示范围|x|<(2^n-1).在运算过程中如出现大于字长绝对值的现象,称为“溢出”,在定点机器中,正常情况下
溢出是不允许的。
例:x=+1011,y=+1001;求x+y
[x]补 01011
【y】补 01001
=============
10100
2个正数相加的结果成为负数,显然是错误的。
参考:计算机组成原理:白中英。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通