原反补码的转换

0、知识点

正整数:原码、反码、补码相同
负整数:原码、反码、补码要进行计算

1、整数在内存中存储的就是补码

通过内存看a的地址 ,把内存调为4列,即看到4个字节, 而这四个字节为什么是这样?
先根据数值写出32二进制- - -原码 1000 0000 0000 0000 0000 0000 1100
原码符号位不变,其他位取反----反码 1111 1111 1111 1111 1111 1111 0011
反码+1-- – -- -补码 1111 1111 1111 1111 1111 1111 0110
补码转换为16进制为 FFFFFFF6(和内存的地址一样)
所以通过十六进制的表示可以看出- - -整数在内存中存储的就是补码
在这里插入图片描述

2、减法运算,但其实cpu中只有加法

先换位补码再进行加法运算

1-1
1+-1
-1的从原码到补码的转换
10000000000000000000000000000001-1的原码)
11111111111111111111111111111110-1的反码)
11111111111111111111111111111111-1的补码)

000000000000000000000000000000011的原码即补码)
11111111111111111111111111111111-1的补码)
100000000000000000000000000000000 (相加之后33位,多出来的高位1被去掉得到下面)
 00000000000000000000000000000000

3大端字节序和小端字节序

大端–把数据的低位字节序的内容存放在高地址处,高位字节序的内容存放在低地址
小端–把数据的低位字节序的内容放在低地址,高位字节序的内容存放在高地址

int  main()
{
  int a=0x11223344;
  return 0;
}

在这里插入图片描述

  • 44为低位字节

在这里插入图片描述

  • vs2013–小端方式

先把a的地址存储再存放b的地址

int  main()
{
  int a=0x11223344;
  int  b=0x01020304;
  return 0;
}

判断当前机器的字节序
在这里插入图片描述
int 在内存中存储涉及大小端- -可以通过上述例子看第一个字节是01还是00来判断大小端更加方便
看第一个字节是什么-- --通过char* p来拿取

int check_sys()
{
	int a = 1;
	char* p = (char*)&a;//int*
	return *p;//返回1表示小端,返回0表示大端
}

int main()
{
	写代码判断当前机器的字节序
	int ret = check_sys();
	if (ret == 1)
	{
		printf("小端\n");
	}
	else
	{
		printf("大端\n");
	}
	return 0;
}

在这里插入图片描述


4、题

相关知识点

  1. char 到底是signed char 还是unsigned char ,C语言标准并没有规定,取决于编译器
  2. 但是默认int 是 signed int ,short 是 signed short
  3. 需不需要提升- -看它本身的类型和打印类型的相差(或者是两种类型的数比较或者加减乘除的时候,有一种需要提升),如本身为char打印用(有无符号)整型打印,需整型提升
  4. 整型提升的时候要看本身是有符号还是无符号,有符号提升加1,无符号提升加0
  5. 整型提升后看得到的数是不是正数,正数–不需要转换为补码,补码即原码,负数–如果不是以无符号来打印则需要转换为补码

打印什么1

#include <stdio.h>
int main()
{
   char a = -1;
   signed char b = -1;
   unsigned char c = -1;
   printf("a=%d,b=%d,c=%d", a, b, c);
 }

解析

#include <stdio.h>
int main()
{
   char a = -1;
    10000000000000000000000000000001 //-1的原码
    11111111111111111111111111111110 //反码
   11111111111111111111111111111111  //补码
    char是一个字节,8个比特位,取32位后面的811111111%d来打印则要按符号位来整形提升得到321
    11111111111111111111111111111111,
  (321是补码要再返回到原码为-1的时候打印,和上述原反补的过程反过来)

signed char b = -1;//也是有符号的,整形提升和打印过程和char a一样
     11111111
  
 unsigned char c = -1;
    11111111
    无符号整型提升
    00000000000000000000000011111111
    整形提升得到的数为正数,则补码为原码

 printf("a=%d,b=%d,c=%d", a, b, c);
 打印:   -1    -1    25
  return 0;
}

打印什么2

%u打印无符号数

#include <stdio.h>
int main()
{
    char a = -128;
     printf("%u\n", a);
      return 0;
}

解析

#include <stdio.h>
int main()
{
   char a = -128;
    -128的原码
   //10000000000000000000000010000000
      反码
   //11111111111111111111111101111111
      补码
    //11111111111111111111111110000000
char是一个字节,8个比特位,取32位后面的8//10000000%u(无符号整型)进行打印--需整形提升---因为char是有符号,则提升的时候有符号提升
    //11111111111111111111111110000000
以无符号来打印的时候,上面的数看成无符号,补码就是原码,直接打印这个很大的数字     
     printf("%u\n", a);
     return 0;
}

打印什么3

#include <stdio.h>
int main()
{
   char a = 128;
   printf("%u\n", a);
   return 0;
}

解析

#include <stdio.h>
int main()
{
   char a = 128;
          //00000000000000000000000010000000 - 原返补相同
          char是一个字节,8个比特位,取32位后面的8//10000000%u(无符号)整型进行打印--需整形提升---因为char是有符号,则提升的时候有符号提升
      //11111111111111111111111110000000
     //以无符号来打印的时候,上面的数看成无符号,补码就是原码,直接打印这个很大的数字
   printf("%u\n", a);
   return 0;
}

char,有符号的取值范围
在这里插入图片描述
以0开头 范围0~127
以1开头 范围-1~-128 (负数要进行原反补的转换)

感觉这个数太大能存储下吗?

char 129
00000000000000000000000010000001
10000001 - 正数-原码-补码
1000000 - 反码
11111111 - 原码
-127

127+1就会变成-128
-128往上走会变成-127…
129也会变为-127- -即127+1+1
圆圈图:
在这里插入图片描述

char类型·无符号-无原反补
在这里插入图片描述

两数相加输出是什么1

输出-10

int main()
{	
    int i = -20;
	unsigned int j = 10;
	printf("%d\n", i+j);
	return 0}

解析

int main()
{	 
int i = -20;
     原码
       	//10000000000000000000000000010100
    反码
      	//11111111111111111111111111101011
    补码
     	//11111111111111111111111111101100

unsigned int j = 10;
    	//00000000000000000000000000001010//正数 原反补 一样
printf("%d\n", i+j);
     两数相加得到负数---补码(如果以%u输出就直接输出这个数就可以了,不用补码转换为原码,因为补反一样)
	 //11111111111111111111111111110110 
    补码转换为反码
	//11111111111111111111111111110101
    反码转换得到原码
   	//10000000000000000000000000001010 -> -10
return 0;
}

两数相加输出是什么2

int main()
{
 	unsigned char b = 200;
    unsigned char b = 100unsigned char c = 0;
  	c = a + b;
    printf("%d %d", a + b, c);
  	return 0;

解析

int main()
{
   //unsigned char 0~255
	unsigned char a = 200;
	//00000000000000000000000011001000(200的原码--正数--即补码)
	//11001000
	
     unsigned char b = 100;
	//00000000000000000000000001100100(100的原码--正数--即补码)
	//01100100
	
	unsigned char c = 0;
	//a和b整形提升 
	//00000000000000000000000011001000
	//00000000000000000000000001100100
	//00000000000000000000000100101100(a+b的二进制)
	
	  c = a + b;
	//00101100(因为c是char类型,char是一个字节,8个比特位,取32位后面的8个)
	//00000000000000000000000000101100(以%d输出整型提升)
	
	printf("%d %d", a + b, c);
	打印:              300   44
	return 0;
//}

输出255

int main()
{
    char a[1000];
    int i;
   for (i = 0; i < 1000; i++)
    {
        a[i] = -1 - i;
   }
  //-1 -2 -3 ... -127 -128 127 126 125 .. 3 2 1 0 -1 -2 .. -127 -128 127 ...(看着圆圈图写,为什么突然出现127,是因为-129没有,所以按照循环的顺序用下一个127,也可以看成256+(-129))
   printf("%d\n", strlen(a))//找到 \0 ,0的前面有128+127 = 255字符
   return 0;
}

无符号的char(永远为正) 0-255,死循环

#include <stdio.h>
unsigned char i = 0;
int main()
{
    for (i = 0; i <= 255; i++)
    {
       printf("hello world\n");
    }

    return 0;
}
int main()
{
	unsigned int i;
	for (i = 9; i >= 0; i--)
	{
		printf("%u\n", i);
	}
	return 0;
	}

知识点

int n,n有四个字节
float 解引用·访问4个字节
double解引用·访问8个字节
char解引用·访问1个字节–8个比特位

  • -浮点型和整型的存储和取出来的方式不一样,
    所以整型n以浮点型打印不会是9.00000
    当再次以浮点型视角存储的时候,以整型打印的时候也得不到9

IEEE754

在这里插入图片描述
题1

 十进制5.5 (小数和小数点后面的数分开来转化,小数为0.52^(-1))
 二进制101.1--->1.011×2^2-- -- --    ---  ->-1^ 0 × 1.011 × 2^2
                 s=0  M=1.011(一般那个小数点前面的1会默认去掉)   E=2(无符号)

题2

十进制:0.5
二进制:0.1--->1.0*2^-1,
 此时E为负数,但是E为无符号
 所以存入的时候float类型加127double1023
  • 在IEEE中M存储小数点后面的数float 32个比特位 double 64个byte

在这里插入图片描述
在这里插入图片描述

浮点型在内存中是怎么样存储的

int main()
{
	float f = 5.5f;
    return 0;
}

解析

int main()
{
	float f = 5.5f;
	//101.1
	//1.011×2^2
	//s=0 M=1.011 E=2
	//s=0 M=011 E=2+127

     根据上面写出 s=0,  E=10000001   M=011 0000 0000 0000 0000 0000
	 //0  10000001 011 0000 0000 0000 0000 0000
     转化成16进制后
     //40 b0 00 00

return 0;
}

看内存
在这里插入图片描述

  • 存入得到32位后想要取出E减去127,M要在小数点后面加回存入的时候去掉的1,E为全0的时候例外

取出可能E全为0或者1,
在这里插入图片描述

打印0.00000

#include <stdio.h>
int main()
{
int n = 9;//4byte
float* pFloat = (float*)&n;
printf("n的值为:%d\n", n);
printf("*pFloat的值为:%f\n", *pFloat);//打印0.00000

*pFloat = 9.0;
printf("num的值为:%d\n", n);//打印一个很大的数
printf("*pFloat的值为:%f\n", *pFloat);//打印9.0
return 0;
}

打印浮点数为0.00000
n为9,以浮点型拿出来,打印浮点数的时候就是0.0000

在这里插入图片描述
打印一个很大的数

*pFloat = 9.0,把9.0存放进去- -得到的二进制为正数–补码为原码,直接打印 ,打印一个很大的数
在这里插入图片描述
float—以%d输出
先写出它的二进制表示,再用科学技术法求出32位二进制
再看它是否正数,补码就是它的本身输出就是这个二进制

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值