4.进制的转换/原码/反码/补码
2022-12-03 本文已影响0人
billgege
1.进制的基本概念
A.什么是进制?
进制数一种计数的方式,数值的表现形式
B.常见的进制有哪些?
十进制、二进制、八进制、十六进制
C.进制书写的格式和规律?
十进制: 0、1、2、3、4、5、6、7、8、9 逢十进1
二进制: 0、1 逢二进1;
书写形式:需要以0b或者0B开头,例如:0b101
八进制:0、1、2、3、4、5、6、7 逢八进一
书写形式:在前面加个0,例如:061
十六进制:0、1、2、3、4、5、6、7、8、9、A、B、C、D、E、F 逢十六进一
书写形式:在前面加个0x或者0X,例如:0x45
2. 不同进制表示与输出
//
// Created by billge on 2022/12/2.
//
/**
* 不同进制表示与输出
*/
#include <stdio.h>
int main() {
/**
* 1.在C语言中如何告诉编译器,当前编写的数值是多少进制的?
* 默认情况下,所有编写的数值都是十进制的
*
* 如果想在C语言中表示一个数值是八进制的,那么必须在前面加上0
* 如果想在C语言中表示一个数值是十六进制的,那么必须在前面加上0x
* 如果想在C语言中表示一个数值是二进制的,那么必须在前面加上0b
*
*
* 2.在C语言中如何以不同的进制来输出某一个数值
* %i/%d以十进制的形式输出数值
* %o 以八进制的形式输出数值
* %x 以十六进制的形式输出数值
* 注意点:
* 在c语言中没有提供以二进制输出的占位符
*/
int num_1 = 12;//默认情况就是十进制
printf("num1 = %i\n", num_1);//%i/%d是以十进制的形式输出数值 num1 = 12
printf("num1 = %o\n", num_1);//14
printf("num1 = %x\n", num_1);//c
int num_2 = 014;//以0开头就是八进制
printf("num2= %d\n",num_2); //num2 = 12
int num_3 = 0xc;//以0x开头的是十六进制
printf("num3= %d\n",num_3); //num3 = 12
int num_4 = 0b1100;//以0b开头的是二进制
printf("num4= %d\n",num_4); //num3 = 12
return 0;
}
3.进制转换
//
// Created by billge on 2022/12/2.
//
/**
* 进制的转换
*/
#include <stdio.h>
int main() {
/**
* 1.十进制转二进制
* 规律:除以2倒序取余
*
* 14
* 2
*-----
* 7 0
* 2
*-----
* 3 1
* 2
*-----
* 1 1
* 2
*------
* 0 1
*=======================
* 倒序:1110
*
*
*
*/
int num = 0b1110;
printf("num=%d\n", num); //num=14
/**
* 2.二进制转十进制
* 规律:系数 × 基数(索引)
* 系数:二进制中每一位对应的值就是系数
* 基数:从二进制转到十进制的基数就是2
* 从八进制转到十进制的基数就是8
* 索引:从二进制的最低位开始,从0开始递增的数就是索引
*
* 1110
*
* 1*2(3) + 1*2(2) + 1*2(1) + 0*2(0)
* =8+4+2+0 = 14
*
*
*/
int num_2 = 0b1110;
printf("num2=%d\n", num_2); //num2=14
/**
* 3.十进制转八进制
* 规律:除以8倒序取余
* 4.十进制转十六进制
*/
/**
* 十进制转八进制
* 24
* 8
*----
* 3 0
* 8
*----
* 0 3
* ==============
* 倒序:30
*
*/
int num_3 = 030;
printf("num_3=%d\n", num_3);//num_3=24
/**
* 十进制转十六进制
*
* 24
* 16
*----
* 1 8
* 16
*----
* 0 1
*=============
* 倒序:18
*
*/
int num_4 = 0x18;
printf("num_4=%d\n", num_4);//num_4=24
/**
* 5.八进制转十进制
* 规律:系数 × 基数(索引)
* 系数:八进制中每一位对应的值就是系数
* 基数:从八进制转到十进制的基数就是8
* 索引:从八进制的最低位开始,从0开始递增的数就是索引
*
* 030
* 0*8(2) + 3*8(1) + 0*8(0)
* = 0 + 24 + 0 = 24
*
*
*/
/**
* 6.十六进制转十进制
* 规律:系数 × 基数(索引)
* 系数:十六进制中每一位对应的值就是系数
* 基数:从十六进制转到十进制的基数就是16
* 索引:从十六进制的最低位开始,从0开始递增的数就是索引
*
* 0x18
*
* 1*16(1) + 8*16(0) = 16 + 8 = 24
*
*/
/**
* 7.二进制转八进制
* 规律:三个二进制位就是一个八进制位
* 案例:01101101
*
* 111 = 7
* 1*2(2) + 1*2(1) + 1*2(0) = 7
* 因为111代表的数值就是7,而八进制的每一位最大的值是7
* 所以三个二进制位代表一个八进制位
* 01101101举例拆分为三个一组,如果不够则补0,如下:
* 001 101 101
* 1 5 5
*
*/
int num_5 = 0155;
printf("num_5=%d\n", num_5);//num_5=109
int num_6 = 0b01101101;
printf("num_6=%d\n", num_6);//num_6=109
/**
* 7.二进制转十六进制
* 规律:四个个二进制位就是一个十六进制位
* 案例:01101101
*
* 1111 = 15
* 1*2(3) + 1*2(2) + 1*2(1) + 1*2(0) = 15
* 因为1111代表的数值就是15,而十六进制的每一位最大的值是15
* 所以四个二进制位代表一个十六进制位
* 01101101举例拆分为四个一组,如果不够则补0,如下:
* 0110 1101
* 6 13(D)====>因为十六进制是0123456789ABCDEF
*
*/
int num_7 = 0x6D;
printf("num_7=%d\n", num_7);//num_7=109
int num_8 = 0b01101101;
printf("num_8=%d\n", num_8);//num_8=109
return 0;
}
4.原码/反码/补码
//
// Created by billge on 2022/12/2.
//
#include <stdio.h>
/**
*
* 原码,反码 和 补码
*
*/
int main() {
/**
* 1.二进制在内存中的不同表现形式
* 原码/反码/补码
*
* 2.正数的原码/反码/补码
* 9--->int类型--->占用4个字节--->1个字节是8位--->总共占用32位
* 0000 0000 0000 0000 0000 0000 0000 1001
* 对于正数来说 ,原码/反码/补码 三码合一
* 正数的原码/反码/补码都是它的二进制
*
* 3.负数的原码/反码/补码
* -9--->int 类型--->占用4个字节--->1个字节是8位--->总共占用32位
* 1000 0000 0000 0000 0000 0000 0000 1001
*
* 二进制的最高位我们称之位符号位,如果是0,代表是一个正数,如果是1,代表是一个负数
* 3.1负数的原码就是负数的二进制
* 3.2负数的反码就是负数的二进制除了最高位以外,按位取反
* 1000 0000 0000 0000 0000 0000 0000 1001
* 最高位不变,其它位1变成0,0变成1
* 1111 1111 1111 1111 1111 1111 1111 0110
* 3.3负数的补码就是负数的反码加个1
* 1111 1111 1111 1111 1111 1111 1111 0110
* +0000 0000 0000 0000 0000 0000 0000 0001
* -----------------------------------------
* 1111 1111 1111 1111 1111 1111 1111 0111
*
*/
/**
* 1.计算机为什么要有原码/反码/补码
* 计算机只能做加法运算
* 1+1 ---> 1+1
* 1-1 ---> 1 + (-1)
* 3*3 ---> 3 + 3+ 3
* 9/3 ---> 9 + (-3) + (-3) + (-3)
*
* 需求:要求计算 1 - 1的结果
* //先用1的原码和-1的原码进行计算
* 0000 0000 0000 0000 0000 0000 0000 0001 1的原码
* 1000 0000 0000 0000 0000 0000 0000 0001 -1的原码
* -------------------------------------------------
* 1000 0000 0000 0000 0000 0000 0000 0010 -2原码
*
* //先用1的反码和-1的反码进行计算
* 0000 0000 0000 0000 0000 0000 0000 0001 1的反码
* 1111 1111 1111 1111 1111 1111 1111 1110 -1的反码
*----------------------------------------------------
* 1111 1111 1111 1111 1111 1111 1111 1111 反码
* 1000 0000 0000 0000 0000 0000 0000 0000 -0原码
*
*
* //先用1的补码和-1的补码进行计算
* 0000 0000 0000 0000 0000 0000 0000 0001 1的补码
* 1111 1111 1111 1111 1111 1111 1111 1111 -1的补码
* ----------------------------------------------------
* 10000 0000 0000 0000 0000 0000 0000 0000
* 0000 0000 0000 0000 0000 0000 0000 0000(最高位被丢弃) 结果就是0
*
* 总结:原码/反码/补码 为了保证计算结果正确
*
*
*/
/**
* 1.在计算机中存储的所有数据都是补码
* 2.在计算机参与运算的都是补码
* 3.如果计算的结果是一个正数,那么直接将计算的结果转换为十进制就是我们想要的结果
* 如果计算的结果是一个负数,那么直接将计算的结果先转换为原码,然后再转换为十进制才是我们想要的结果
*
* 4. 原码如何转换为反码
* 符号位不变,其它位按位取反
* 5. 反码如何转换为补码
* 反码 + 1
*
* 6. 补码如何转换为反码
* 补码 - 1
*
* 7.反码如何转为我们的原码
* 符号位不变,其它位按位取反
*
* 9-6 ---> 9 +(-6)
* 思路:需要先拿到9的补码 和 -6的补码
*
* 9的原码 0000 0000 0000 0000 0000 0000 0000 1001
* 9的反码 0000 0000 0000 0000 0000 0000 0000 1001
* 9的补码 0000 0000 0000 0000 0000 0000 0000 1001
*
* -6的原码 1000 0000 0000 0000 0000 0000 0000 0110
* -6的反码 1111 1111 1111 1111 1111 1111 1111 1001
* -6的补码 1111 1111 1111 1111 1111 1111 1111 1010
*
* 9的补码 0000 0000 0000 0000 0000 0000 0000 1001
* -6的补码 1111 1111 1111 1111 1111 1111 1111 1010
* ---------------------------------------------------
* 10000 0000 0000 0000 0000 0000 0000 0011 去掉溢出的最高位1
* 0000 0000 0000 0000 0000 0000 0000 0011 ---->转换为十进制,结果是3
*
*
*
*
* 4 - 6 --> 4 + (-6)
*
* 4的原码 0000 0000 0000 0000 0000 0000 0000 0100
* 4的反码 0000 0000 0000 0000 0000 0000 0000 0100
* 4的补码 0000 0000 0000 0000 0000 0000 0000 0100
*
* -6的原码 1000 0000 0000 0000 0000 0000 0000 0110
* -6的反码 1111 1111 1111 1111 1111 1111 1111 1001
* -6的补码 1111 1111 1111 1111 1111 1111 1111 1010
*
* 4的补码 0000 0000 0000 0000 0000 0000 0000 0100
* -6的补码 1111 1111 1111 1111 1111 1111 1111 1010
*---------------------------------------------------
* 1111 1111 1111 1111 1111 1111 1111 1110
* 由于参与运算的都是补码,所以得到的结果也是补码,并且得到的结果是一个负数,
* 所以需要先转换为原码===>(补码-->转为反码--->反码再转为原码)
* 补码转反码需要 -1
* 1111 1111 1111 1111 1111 1111 1111 1110 补码
* 1111 1111 1111 1111 1111 1111 1111 1101 反码 (补码-1)
* 1000 0000 0000 0000 0000 0000 0000 0010 原码(符号位不变,其它位取反)
*
*
*/
return 0;
}