c语言的原码补码反码-位运算

c语言的原码补码反码-位运算

计算机内存负数的时候是存的补码容易运算

有无unsigned 的区别
数据在计算机上存储是2进制的 第一位是符号位 其余是数据位
unsigned 是无符号的意思 没有符号位 全都是数据位
比如
unsigned int int 占4字节8位在内存中
0000 0000 0000 0000 0000 0000 0000 0000
int 也占4字节8位 这时候第一位为符号位
1 000 0000 0000 0000 0000 0000 0000 0000
综上所属
int 类型最大值为2^31(^是多少次方不是异或)2147483648
unsigned int 类型最大值为2^32 4294967296
short 类型2字节16位
unsigned
0000 0000 0000 0000 2^16 65536
short
1 000 0000 0000 0000 32768
等等….

废话不多说上例子

#include<stdio.h>
#include<stdlib.h>
int main()
{
    //右移 >>
    //正 
    char ch1 = 2;
    //2用2进制表示 char 类型是1字节8位
    //            0000 0010 :2
    //向右移动1位   0000 0001 :1
    printf("%d",ch1>>1);//向右移动 结果1
    //负数
    char ch2 = -2;
    //1000 0010 -2的原码
    //1111 1101 -2的反码 反码就是在原码的基础上符号位不变其余位置0变1 1变0;
    //1111 1110 -2的补码 补码就是在反码的基础上加1 
    //我们这时候对-2进行移动 1111 1111
    printf("%d",ch2>>1);//向右移动 结果-1

    //左移<<
    //正 
    char ch3 = 2;
    //2用2进制表示 char 类型是1字节8位
    //            0000 0010 :2
    //向左移动1位   0000 0100 :4
    printf("%d",ch3<<1);//向右移动 结果4
    //负数
    char ch4 = -2;
    //1000 0010 -2的原码
    //1111 1101 -2的反码 反码就是在原码的基础上符号位不变其余位置0变1 1变0;
    //1111 1110 -2的补码 补码就是在反码的基础上加1 
    //我们这时候对-2进行移动 
    printf("%d",ch4<<1);//向右移动 结果-4 补码:1111 1100 原码1000 0100



}

位运算 ~取反 &逻辑与 |或运算 ^异或

嵌入式节约内存
比如1个字节有8位 每一个位都有2个状态
所以控制灯的时候 1字节 就可以控制8个灯泡的开关

    //逻辑与
    //这里假设嵌入式设备返回的数据位
    //我们用逻辑与判断 1&1 = 1 1&0 = 0 0&0 = 0
    unsigned char ch = 0x0A;//00001010

    int arr[] = {0x08,0x04,0x02,0x01};
    //0x08 0000 1000
    //0x04 0000 0100
    //0x02 0000 0010
    //0x01 0000 0001
    //分别与0x0a 进行逻辑与判断哪盏灯亮
    for(int i = 0;i<4;i++)
    {
        int temp = arr[i];
        printf("%d",temp);
        if((temp&ch)!=0)
        {

            printf("第%d盏灯亮\n",i+1);
        }
        else
        {
            printf("第%d盏灯灭\n",i+1);
        }
    }
    //取反 1变0 0变1 
    unsigned char ch = 1;//0000 0001 
                        //~1 1111 1110补码显示
                        // 1111 1110 反码 1111 1101
                        //1111 1101原码 1000 0010 -2
    printf("%d",~1);//结果位-2
                        //~2 1111 1101
                        // 1111 1101反码 1111 1100
                        //1111 1100 原码 1000 0011

    printf("%d",~2);//结果位-3

    //|或运算  1|1=1 1|0=1 0|0=0
    //2 0000 0010
    //1 0000 0001
    //2|1 0000 0011 :3
    printf("%d",2|1);//3
    //2 0000 0010
    //-1 1000 0001原码 这里要转化为补码显示
    //1111 1110 -> 1111 1111 补码
    //2|-1 1111 1111 :-1

    printf("%d",2|-1);//-1

    //^异或 1^1 = 0 0^1 = 1 0^0 = 0 
    //2 0000 0010
    //1 0000 0001
    //2^1 0000 0011 :3
    printf("%d",2^1);//3
    //2 0000 0010
    //-1 1000 0001原码 这里要转化为补码显示
    //1111 1110 -> 1111 1111 补码
    //2|-1 1111 1101
    //1111 1101 反码 1111 1100
    //1111 1100 原码 1000 0011 :-3
    printf("%d",2^-1);//-3

    //异或应用交换两个数值
    //比如 x=100 ;y=200; x = x+y; y = x-y; x = x-y;

    int ch1= 10;
    int ch2= 20;
    printf("%d,%d\n",ch1,ch2);
    ch1 = ch1^ch2;
    ch2 = ch1^ch2;
    ch1 = ch1^ch2;
    printf("%d,%d\n",ch1,ch2);

综合应用求余数这里有bug一直没找出来 求大虾找bug

    //综合应用求余数这里有bug一直没找出来
    int st= 19; //求余 3
    //19        0001 0011
    //~2       1111 1101  
    //19 & ~2  0001 0001
    printf("%d\n",st - (st&(~2))); 

近期看着000111看多了 建议小伙伴多出去春游 不要一直撸代码

发布了18 篇原创文章 · 获赞 11 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/INTKILOW/article/details/70176082