有符号数与无符号数的加减法

本文详细介绍了计算机中如何处理有符号数和无符号数的加减法运算,包括补码的概念及其在运算中的应用,并通过实例展示了补码运算的具体步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

声明
本博文源自:原文链接已失效,现已不引用了
在此感谢博主!


一.有符号数的加减法
1、符号数与无符号数的人为规定性:一个数是有符号还是无符号数都是人为规定的。进行二进制运算时用无符号数或是补码运算时,结果都是正确的。0b10000100 + 0b00001110 若规定为无符号数,即 132+14=146 。若规定为有符号数,则为 -124 + 14 = -110,而[-110]补= 0b10010010。解释:0b10000100 是 -124 的补码,0b00001110 是 14 的补码,在机器中运算后得出的结果是 [-110] 的补码。机器中的有符号数运算一般就是补码运算。

2、补码加减法运算:计算机中,当确定为有符号数运算时,符号数一律用补码表示,运算时符号位和数字位一起参加运算。运算结果也用补码表示。

  • 两符号数相加公式:[X+Y]补=[X]补 + [Y]补
  • 两符号数相减公式:[X-Y]补 = [X]补 + [-Y]补

例子:求 0x3C - 0x90。首先 0x3C = 0b0011 1100,0x90 = 0b1001 0000
(1)当为有符号数时,显然这两个数是某两个数的补码。(具体是哪两个数X Y, 需要自己计算)。运算结果也是补码,是X-Y的补码 [X-Y]补。机器只运算到这一步。[X-Y]补 就是运算结果,溢出进位等标志位也都是这个补码运算过程的结果,由硬件ALU运算。X-Y并不是机器的运算结果,由[X-Y]补求X-Y是人或者编译器完成的工作,对于编译器来说运算结果才是X-Y。补码的减法要转换成补码的加法。根据有符号数的减法公式,[x]补-[Y]补=[x]补+[-Y]补=[X-Y]补,[x]补=0011 1100,[Y]补=1001 0000,其中求[-Y]补是关键。[-Y]补= {-[Y]补} mod 2^8,即[-Y]补={-[Y]补} 的求补操作(即-[Y]补 的补码)(即 按位取反再加一,这是机器真正的过程)。所以,[-Y]补=0111 0000,所以,[X-Y]补 = 0b0011 1100 - 0b1001 0000 = 0b0011 1100 + 0b 0111 0000 = 0xAC

(2)补码最大好处就是不管是有符号数还是无符号数都可以用同一套加减法。系统对有符号数和无符号数的加减法都采用一样的策略。无符号加减法不存在溢出问题,只是将进位或借位存储在CF中。机器不知道你进行的运算是否有符号,如果你进行的是有符号运算,你需要查看OF,否则不需要。所以,溢出不溢出,是由程序员判断的,机器不知道。不管是有符号数还是无符号数,系统都是按补码运算,至于是进位还是溢出不仅要看进位标志位,还要看溢出标志位。只不过在做无符号数运算时程序员不考虑溢出标志位,只考虑进位标志位而已。比如 0111+1101 ,你说它是无符号数7+13呢,还是有符号数 7-3 呢?
对系统而言这是一回事!所以,无符号数和有符号数的运算结果一定是一样的。

(3)注意这道题和《计算机组成原理》学补码加减运算时的题目的区别。例子:X=+0101,Y=-1010,求X-Y。题目给的X,Y 是原码, 所以已经默认是有符号数,也有判断是否溢出,所以默认的计算过程也是指机器运算过程。原码在机器中均是以补码保存和运算的,[x]补-[Y]补=[x]补+[-Y]补=[X-Y]补,只用到了[x]补+[-Y]补=[X-Y]补属于类型:已知X Y,所以先求[X]补, [-Y]补 ,便求得[X-Y]补。然后再求X-Y。也就是说,上一题已知的是[X]补 [Y]补,(机器的)运算结果是[X-Y]补。中间过程没必要求出X Y是什么数。本题已知的是X Y,先得出机器的运算结果[X-Y]补,再做编译器的工作由[X-Y]补求出X-Y。二者求[-Y]补的方法不一样:前者是由-[Y]补 求得的,后者是先求-Y,然后求[-Y]补。可以说,后面例子是编译器和系统共同工作的过程,前面例子只关系系统运算。

二.那么系统是怎么识别有符号数和无符号数的呢?
(1)CPU只会根据输入信号进行逻辑运算,在硬件级别是没有无符号有符号的概念,运算结束会根据运算前的信号和输出信号来设置一些标志位,是不是有符号由写程序的人决定,标志位要看你把操作数当有符号还是无符号来选择,就像内存中的数据,你可以按照需要来解析,原始数据在那里,你要按什么数据格式来解析在于自己的选择;
在汇编语言层面,声明变量的时候,没有 signed 和 unsigned 之分,汇编器统统将你输入的整数字面量当作有符号数处理成补码存入到计算机中,只有这一个标准!
(2)计算机对有符号整数的表示只采取一套编码方式,不存在正数用原码,负数用补码这用两套编码之说,大多数计算机内部的有符号整数都是用补码,就是说无论正负,这个计算机内部只用补码来编码!!!只不过正数和0的补码跟他原码在形式上相同,负数的补码在形式上与其绝对值的原码取反加一相同。
(3)有符号数和无符号数在计算机里表示都是一样的,即二进制的补码形式。是有符号还是无符号,是编译器来辨认的。

例如:
unsigned char uch, char ch;
在内存中有个数 0b11111111(补码)
把它赋给 uch,那么 uch 就是 255(正数的补码等于原码)
如果赋给 ch,那么 ch 就是 -1(负数的补码等于其除符号位外的原码取反+1)

说白了,内存中是补码值,代码中是原码值,代码中的原码到内存中的补码的双向转换是编译器根据原码补码规则自动处理的

<think>我们正在讨论SystemVerilog中的数据类型,特别是int类型的有符号性。根据引用[1]引用[3]中的信息: 引用[1]提到: "如果按照有符号无符号的类型划分,那么可以将常见的变量类型划分为: 有符号类型:byte/int/shortint/longint/integer 无符号类型:bit/logic/reg/net-type(wire、tri)" 这里明确将int列为有符号类型。 引用[3]中也提到: "双状态型(bit、byte、int、shortint、longint)" 并在后续说明中,byte、int、shortint、longint都是有符号的(因为byte是8位有符号,int是32位有符号等)。 因此,SystemVerilog中的int类型默认是有符号的。 同时,根据SystemVerilog标准,int类型是32位二值有符号整数。 所以,回答如下:</think>在SystemVerilog中,**`int`类型默认是有符号的(signed)**。这是由SystemVerilog标准明确规定的数据类型特性。以下是详细说明依据: ### 1. **`int`类型的有符号特性** - **定义**:`int`是32位(4字节)二值逻辑数据类型,采用**二进制补码**表示负数[^1][^3]。 - **符号性**:默认带符号位(最高位为符号位),可表示范围:$-2^{31} \text{到} 2^{31}-1$(即 $-2147483648 \text{到} 2147483647$)[^1][^3]。 - **示例**: ```systemverilog int a = -10; // 合法赋值,负数存储为补码 int b = 10; // 正数直接存储 ``` ### 2. **关键引用依据** - 引用[1]明确分类: > 有符号类型:`byte`/`int`/`shortint`/`longint`/`integer` > 无符号类型:`bit`/`logic`/`reg`/`net-type`(如`wire`)[^1]。 - 引用[3]进一步说明: > `int`属于双状态型(二值逻辑)有符号整数,`byte`(8位有符号)、`shortint`(16位有符号)同属有符号类型[^3]。 ### 3. **有符号无符号类型对比** | **数据类型** | **符号性** | **位数** | **值逻辑** | **表示范围** | |----------------|------------|----------|------------|----------------------------| | `int` | 有符号 | 32位 | 二值(0/1)| $-2^{31} \text{到} 2^{31}-1$ | | `bit` | 无符号 | 1位 | 二值(0/1)| $0 \text{或} 1$ | | `logic` | 无符号 | 自定义 | 四值(0/1/x/z)| $0 \text{到} 2^{n}-1$ | | `integer` | 有符号 | 64位 | 四值(0/1/x/z)| $-2^{63} \text{到} 2^{63}-1$ | ### 4. **使用注意事项** - **显式声明**:若需无符号操作,需强制转换: ```systemverilog int signed_data = -1; // 有符号,值为-1 bit [31:0] unsigned_data = int'(signed_data); // 强制转为无符号,值为4294967295 ``` - **运算影响**:有符号类型参运算时保留符号语义(如负数左移补0可能变正数[^1])。 ### 5. **总结** - `int` **始终是有符号类型**,无需额外声明`signed`关键字[^1][^3]。 - 无符号操作需显式类型转换(如`bit`或`logic`)以避免意外行为。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值