信息的表示和处理

本文深入探讨了计算机中数字的补码表示方法,包括原码的概念、补码的转换过程以及有符号数与无符号数的转换。详细介绍了C语言中整型数据的有符号与无符号运算,以及不同数据类型之间的转换规则,特别是溢出和截断处理。文章旨在提供全面理解补码表示与整数操作的基础知识。

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

计算机中的数字均以补码的形式表示
原码

原码表示法在数值前面增加了以为符号位(最高位为符号位)

正数该位为0,负数该位为1(0有两种表示:+0和-0),其余位表示数值的大小。

例如,我们用8位二进制表示一个数,+11的原码为00001011,-11的原码就是10001011

补码

正数的补码与原码相同

负数的补码对其原码逐位取反,但符号位除外;然后整个数加1。

-7的原码(10000111)→按位取反(11111000)(负数符号位不变)→加1(11111001)

正数的补码转换为负数的补码

正数补码与原码,反码都相同,只要把正数补码的最高位设为1,其他位求反,然后+1

12345的补码0011000000111001

-12345的补码1100111111000111

有符号数转换为无符号数(强制类型转换):

不改变参数的位的表示,只是改变了如何讲这些位解释为一个数字

有符号-1234561100111111000111

无符号 531911100111111000111


C语言中的有符号与无符号数

C语言支持所有整型数据类型的有符号与无符号运算,大多数数字都被认为是有符号的.

例如,当声明一个像12345或者0x1A2B这样的常量时,这个值就被认为是有符号的

C语言中无符号和有符号的转换(强制类型转换),隐式类型转换 int tx,ty; unsigned ux,uy;tx = ux, uy = ty;

底层的位表示保持不变

C语言对同时包含有符号与无符号数表达式的处理方式

C语言会隐式的的将有符号参数强制类型转换为无符号数,并假设这两个数都是非负的

例如: -5 + 3

1011 + 0011 = 1110

从一个数据大小到另一个数据大小的转换,

以及无符号和有符号数字之间的转换的相对顺序能够影响一个程序的行为

C语言标准要求 short转换成unsigned既(unsigned)short等价于(unsigned)(int)short

扩展一个数字的位的表示

从一个较小的数据类型转换到一个较大的数据类型:

无符号数:零扩展 即在位模式的开头添加0

二进制补码:符号扩展 在表示中添加最高有效位的值

截断数字

将一个w位的数截断为一个k位的数时,我们会丢弃w-k位.(可能会产生溢出)

32位int x = 53191(x 0000 0000 0000 0000 1100 1111 1100 0111); 

short sx = (short)x (sx1100 1111 1100 0111 -12345的补码);

对于一个无符号数字x,截断它到k位的结果

x mod 2的k次方

例如 无符号15截断1位 1111 截断 1位 等于111 (7)

补码 -1截断1位 1111 截断 1位 等于111(-1)

关于有符号与无符号的建议

绝不使用无符号数

java只支持有符号整数,并且要求用补码来实现,正常的右移>>被定为算数右移(前面补0).

特殊的运算符>>>被定为逻辑右移(前面补最高位的副本)

无符号(无符号)加法

截取掉高位,留下低w位表示的值

溢出是指一个算数运算的整数结果不能放到数据类型的限制中去

例如:四位数字表示,x=9,y=12;的位分别表示[1001],[1100]他们的和位21,五位的表示为[10101]

无符号加法运算等价于计算模2的w位次方的和, 上例中 21 mod 2的4次方


判断发生了溢出

int uadd_ok(unsigned x, unsigned y){
     int sum = x + y;
     return sam >= 0;
}

有符号无符号乘法

截取掉高位,留下低w位表示的值










评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值