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;
}
上一篇下一篇

猜你喜欢

热点阅读