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

简介: 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。


目录
打赏
0
0
0
0
24
分享
相关文章
截断&&整型提升&&算数转换
截断&&整型提升&&算数转换
C语言:截断+整型提升+算数转换练习
截断+整型提升+算数转换练习
90 0
C语言之数据的存储2(浮点数在内存中如何存储,如何输出,查看不同类型数据在内存中表示的范围的方法,十进制浮点数转化为二进制的方法)
C语言之数据的存储2(浮点数在内存中如何存储,如何输出,查看不同类型数据在内存中表示的范围的方法,十进制浮点数转化为二进制的方法)
168 0
用栈实现将一个十进制数值转换成八进制数值。即用该十进制数值除以8,并保留其余数;重复此操作,直到该十进制数值为0为止。最后将所有的余数反向输出就是所对应的八进制数值
这篇文章展示了如何使用栈(包括顺序栈和链栈)实现将十进制数值转换成八进制数值的方法,通过C语言编程演示了两种栈的实现方式和使用场景。
用栈实现将一个十进制数值转换成八进制数值。即用该十进制数值除以8,并保留其余数;重复此操作,直到该十进制数值为0为止。最后将所有的余数反向输出就是所对应的八进制数值
【C语言】数据的存储(基本类型介绍、原码、反码、补码详解、大小端的理解、浮点数的存储规则)
【C语言】数据的存储(基本类型介绍、原码、反码、补码详解、大小端的理解、浮点数的存储规则)
150 0
|
10月前
|
计算32位二进制整数中1的个数(包括负数补码)
计算32位二进制整数中1的个数(包括负数补码)
156 0
数据在内存中的存储(浮点数与整数的类型转换)
在c语言操作符那一篇文章中我们讲到整数的二进制表示方法有三种,即原码、反码和补码。 它们都由符号位和数值位组成,数值位中的最高位就是符号位,符号位中0表示”正“,1表示”负“,
C语言之(有关%d和%u的有关内容,输出方法)(有符号和无符号在内存中的存储情况)(整形无符号数和有符号数是如何进行计算的,整形无符号数和有符号数在循环中的应用举例)
C语言之(有关%d和%u的有关内容,输出方法)(有符号和无符号在内存中的存储情况)(整形无符号数和有符号数是如何进行计算的,整形无符号数和有符号数在循环中的应用举例)
612 0
数组形式的整数加法
数组形式的整数加法
108 0

热门文章

最新文章

AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等