CSAPP学习笔记——Integer Representation

本文详细介绍了计算机中整数的二进制表示,包括无符号和有符号整数的补码表示,以及整数之间的转换、扩展和截断。此外,还探讨了整数加法、取反、乘法等运算,特别是溢出处理和无符号到有符号的转换问题,对理解计算机底层运算机制非常有帮助。
摘要由CSDN通过智能技术生成

整数的二进制底层表示

对于字长(word size)为w的机器,用w位bit表示一个字(word)。

[xw1,xw2.....x0]

无符号整数的二进制表示

如果该字表示一个无符号整数的话,我们可以用下列公式来计算

unsinged=i=0w1xi2i

范围 : 0<=x<2w1

有符号整数的二进制表示

如果该字表示一个有符号整数的话,现代计算机通常使用补码(two’s complement)方式的编码方式。
补码的确定规则基于这样的事实:
对于一个正整数x,它的相反数y,那么 x+y=0 是符合我们的直觉的。
对于 [xw1,xw2.....x0] 例如 x=0000001 想找另外的一个 [yw1,yw2.....y0] y使得 x+y=0000000 (如果 bitlen(x+y)==w+1 截断最高位)那么 y=1111111 推导出 y= x+1
因为 x=0000001 表示正整数的1,为了使得 y=1111111 表示-1,我们采用以下公式 :

signed=xw12w1+i=0w2xi2i

我们给了最高位一个很大的负权重来达到我们的目的。
范围 : 2w1<=x<=2w11
这种编码方式成为补码。

使用 <stdints.h><inttype.h>

由于不同机器的字长(字长影响数据范围)不同,c语言在不同字长的机器上int的大小可能略有区别,考虑到可移植性,我们应该尽量使用c99标准库的<stdints.h<inttype.h>中的类型。

int main(void)
{
    int16_t  x0 = 10;
    int32_t  x1 = 10000;
    int64_t  x2 = 1000000000000;
    printf("x0 : %d\n",x0);
    printf("x1 : %d\n",x1);
    printf("x2 : %" PRId64 "\n", x2);
    return 0;
}

需要注意的是输出int64_t的时候使用PRId64这是<inttype.h>中的一个宏。

有符号整数和无符号整数之间的转换

c语言中一旦操作符某一边出现了unsigned int那么都会被自动转换为unsigned int这种转换是隐式的不宜察觉,很多bug由此出现。应当了解具体的细节。
转换的时候,bit sequence是不会改变的,只是编译器对它的解释方式发生变化。

有符号->无符号

singned>unsigned={ x+2w,x<0x,x>=0

看一个例子 :

int x = -50;//signed
unsigned y = 1;
if(x > y)
    printf("ok\n");

程序输出为ok,这是因为if(x > y)这条语句,x是signed,y是unsigned,x会自动cast为unsiged,根据上边的公式可知,cast后必定大于1,所以会输出ok

无符号->有符号

unsingned>signed={ x,x<2w1x2w,x>=2w1

看一个例子 :

unsigned x = (1 << 31);
int y = x;
printf("x = %ud , y = %d\n",x,y);
x = 2147483648d , y = -2147483648

套用上述公式即可解释

整数二进制表示形式的扩展和截断

不同字节的整数转换是一种常见的操作。

无符号整数的扩展

对于w字长的无符号整数 [xw1,xw2

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值