由按位取反复习原码和补码知识

今天遇到一个问题,问下面程序的输出结果是多少。

#include <stdio.h>
int main()
{    
    int i = 1;    
    printf("%d\n", ~i);   
    return 0;
}

我们首先要知道按位取反(~)的运算规则:
~1=0; ~0=1;

第一反应,这不就是0吗?
啊呸,问题不可能这么简单,~i又不是 ~1!

记得int类型的本质是4字节补码,呃…什么补码?什么原码?不好意思,之前学的计算机基础知识又还给教材了,hhh…

无奈,回去复习,结合问题又做了一番整理,把思路排版出来,仅供参阅:


我是一条华丽的分割线

呸,走错地方了,这又不是知乎。

好,我们来看题,题目定义了int i=1,问~i的输出结果是多少。

首先我们要明确计算机表达数值的特点

  1. 二进制,由于数字电路的两种状态,计算机内部只能用0和1两种符号表达数值。在这个条件的约束下,计算机能够表达的数值只能是正整数或0,因为计算机表达数值时没有正、负号和小数点。
  2. 定长,计算机用固定位数的二进制表达数值。

再回顾原码定义:

令n位二进制数中的最高位为符号位,且0表示正号,1表示负号,用剩余的n-1位表示该数的绝对值,即形成原码。
比如在8位二进制下我们表示3的原码:0000 0011
-3的原码:1000 0011

我们再来看补码:

x的补码,当x>=0时,(x)补=(x)原=x;当x<0时,(x)补是在(x)原基础上进行:除符号位外,按位取反,末位加一。
比如(-3)补=(1000 0011)原=(1111 1100+1)补=
(1111 1101)补

然后我们分析一下,i 是int类型,就是说i是以4字节补码形式存储在计算机的,一个字节8个位,4*8=32,共32个位。又因为i 的值为1,所以计算机内存中的1的补码应该是:
(0000 0000 0000 0000 0000 0000 0000 0001)补
将上述二进制数按位取反,将得到:
(1111 1111 1111 1111 1111 1111 1111 1110)补
按补码和原码的关系,转成原码为:
(1000 0000 0000 0000 0000 0000 0000 0010)原
上述原码的十进制值是:-2

所以,~i输出的结果是-2!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值