C中负数的存储形式 | 位运算符

位运算符

C语言中,一共有6个位运算符,优先级由高到低分别是(其中<<>>优先级相同)~ , << , >> , & , ^ , |
分别说明:

位运算符作用
~按位取反,1变为0, 0变为1
<<左移,最高位舍,最低位补0,例: 0000 0000 0000 1001 左移1位, =>0000 0000 0001 0010
>>右移 , 最低位舍,最高位补0, 例:0000 0000 0000 1001 右移一位 =>0000 0000 0000 0100 ,
&按位与,只有当其同为1时,才为1,否则为0
^按位异或,相同为0,不同为1。只有两个不同时,才为1,否则为0
|按位或,有1为1,没有为0,只要两者中存在一个1,就为1,两个都是1也为1,否则为0

注意: 1001>>1 并不等于100,这里的1001表示的是10进制数,想表示二进制数1001,需加上前缀0b,即0b1001。

  • M<<N,表示将M左移N位,所得的数相当于,M乘以2的N次方
  • 例: 要得到2的3次方, 1<<3效率最高,而不是2 * 2 * 2或者 pow(2,3)
  • 类似的,M>>N,表示将M右移N位,所得的数相当于,M除以2的N次方,整数与整数相除结果也为整数,注意。
  • 例: 9>>1 , 结果为9/2等于 4
  • 如果整数a,b相等,可得到 a^b等于 0 . 即 if(a!=b)等价于if(a ^ b)
  • 大小写转换: x^=32 , 如输入A(65),转换为a(97); 如输入z(122),转换为Z(90)
  • 实例:将输入的字符串,大写转小写,小写转大写
int main(){
    char str[10], *p;
    p = str;
    scanf("%s", p);
    for (int i = 0; str[i] != '\0'; i++)
        str[i] ^= 32;
    printf("%s", p);
    return 0;
}

负数的存储形式

按编译系统不同,整形在C中占用2字节或4字节, 一字节8位 .
以下讨论的按2字节举例: 只讨论整形 .
说负数的存储形式前,先说正数的存储形式 , 正数的存储形式,就是其二进制.
例:1 的存储形式,0000 0000 0000 0001
9的存储形式: 0000 0000 0000 1001
而 负数的存储形式是其绝对值的存储形式按位取反,再加一 .

此处按4字节算:
整数1的存储方式:
	0000 0000,0000 0000,0000 0000,0000 0001
整数 -1 的存储方式:
	0000 0000,0000 0000,0000 0000,0000 0001
	按位取反:
	1111 1111,1111 1111,1111 1111,1111 1110
	再加上1:
	1111 1111,1111 1111,1111 1111,1111 1111
	所以整数 -1 的存储方式为:
    1111 1111,1111 1111,1111 1111,1111 1111

案例

#include <stdio.h>

int main(){
    int x = M;
    printf("%d",~x);
    return 0;
}
  • M为一个整数常量 , 输出的值始终为 -(M+1),如当M为1时,输出打印 -2
  • 为啥?

首先,就要说到C语言中,负数的存储形式:负数的存储形式是其绝对值的二进制形式 按位取反再加一

例: -1 (如整形按两个字节计算)

其绝对值 1 的二进制形式: 0000 0000 0000 0001

按位取反 ~: 1111 1111 1111 1110

再加一: 1111 1111 1111 1111

所以-1在内存中的存储形式为: 1111 1111 1111 1111

内存中,首位(最高位)为0,表示一个正数,为1表示一个负数。

所以,当遇到存储形式为:0000 0000 0000 0001 的, 首先看其最高位是0(是正数)还是1(还是负数)。

如是 0 :则直接按二进制转十进制, 0000 0000 0000 0001的十进制便是 1,所以其表示的也是1。

如存储形式为:1000 0000 0000 0001,最高位为1,便不可直接按二进制转十进制得到 32769,

因为最高位为1,代表负数,而负数的存储方式与正数不同,不可直接转化为十进制,需先减一,再按位取反,回推。

减一: 1000 0000 0000 0000

按位取反:0111 1111 1111 1111

再转十进制:32767

又因首位是1,表示负数,所以1000 0000 0000 0001所表示的数是 -32767,并不是-1,也不是32769。

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

梦中千秋

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值