有符号整型和无符号整型的计算

本文解析了int类型和unsigned int类型的位数及运算原理,并通过一个具体的例子展示了如何使用补码来计算不同类型的整数相加的结果。
int 类型占四个字节,一个字节8位,即int类型有32位
unsigned int 占2个字节,即16位
以一道题为例:
       unsigned int i=10;
       int j=-20;
       i+j=?
在程序中负数用补码进行运算,int为32位,所以-20的补码是1111 1111 1111 1111 1111 1111 1110 1100,unsigned int i=10 为16位,即0000 0000 0000 1010,相加得到1111 1111 1111 1111 1111 1111 1111 0110,换算成十进制,所以i+j=4294967286。
程序如下:
运行结果如下:
C语言中,当有符号整型无符号整型一起参与运算时,会遵循一套特定的类转换规则。这些规则旨在确保操作数具有相同的类,以便能够执行算术运算[^1]。 ### 类提升(Integer Promotion) 首先,在任何算术运算之前,小于`int`或`unsigned int`大小的操作数(例如`char`, `short`等)会被提升到`int`或者`unsigned int`类。这种提升是为了保证运算在至少是`int`大小的数据上进行[^1]。 ### 类转换(Usual Arithmetic Conversions) 一旦完成了类提升,接下来就会应用通常的算术转换来使两个操作数具有相同的类。对于有符号整型无符号整型之间的运算,如果其中一个操作数的类是无符号的,并且其等级不低于另一个操作数的类,则另一个操作数将被转换为无符号类[^1]。 具体来说: - 如果两个操作数都是相同类的,则不需要转换。 - 如果两个操作数都不是有符号整型,那么结果将是无符号的。 - 如果存在一个无符号操作数,而另一个是有符号但不能表示所有可能的无符号值(比如,当比较一个`int`一个`unsigned int`时),那么有符号的操作数会被转换为无符号类[^1]。 以给出的例子来看: ```c #include <stdio.h> int main() { int x = -1; unsigned int y = 1; printf("x+y=%d\n", x + y); // 输出取决于x+y的实际计算结果 if (x < 0u) { // 这里x会被隐式转换成unsigned int printf("yes!\n"); } else { printf("no!\n"); // 预期输出"no!" } return 0; } ``` 在这个例子中,变量`x`是一个有符号整数,初始化为-1;而`y`是一个无符号整数,初始化为1。当执行`x + y`时,`x`会被转换成无符号整数。由于-1在二进制补码形式下全为1,当它被解释为无符号整数时,代表的是最大的可表示数值(对于32位系统而言是4294967295)。因此,`x + y`的结果实际上会溢出并产生一个非常大的正数,但用`%d`格式化字符串打印时,这可能导致未定义行为,因为`%d`期望接收一个有符号整数,而传递给它的可能是超出`int`范围的无符号值。 至于条件判断`if (x < 0u)`,这里的`0u`是一个无符号整数字面量。在这种情况下,`x`会被隐式转换成无符号整数来进行比较。由于`x`的值是-1,当它被转换成无符号整数时,它变成了一个非常大的正数,所以这个条件实际上评估为假,导致程序打印出`no!`[^2]。 综上所述,理解这类问题的关键在于认识到C语言如何处理不同类之间的隐式转换,尤其是当涉及到负数与无符号类之间的交互时。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值