Saul's blog Saul's blog
首页
后端
分布式
前端
更多
分类
标签
归档
友情链接
关于
GitHub (opens new window)

Saul.J.Wu

立身之本,不在高低。
首页
后端
分布式
前端
更多
分类
标签
归档
友情链接
关于
GitHub (opens new window)
  • Java入门基础

    • 计算机常识

    • Java语言概述

    • 基本语法

      • Java-关键字与保留字
      • Java-标识符(Identifier)
      • Java-变量
      • Java-基本数据类型-整型
      • Java-基本数据类型-浮点型
      • Java-基本数据类型-char字符
      • Java-基本数据类型-boolean布尔类型
      • Java-基本数据类型之间的运算规则
      • 字符串类型 String
      • 进制
        • 关于进制
        • 进制关系表
        • 练习
        • 二进制
          • 二进制转换十进制
          • 1110
          • 1101110
          • 10001110
          • 10111011
          • 填坑
        • 进制之间的转化
          • 十进制转二进制
          • 二进制 转 八进制
          • 二进制 转 十六进制
          • 八进制 转二进制
          • 十六进制 转二进制
        • Java 二进制API
      • 运算符
      • Scanner类
      • 流程控制-分支结构
      • 流程控制-循环结构
    • 数组

    • 面向对象

    • 异常处理

  • Java核心基础

  • 设计模式

  • Web开发

  • SpringBoot

  • 微服务

  • Elasticsearch

  • 运维

  • 后端
  • Java入门基础
  • 基本语法
SaulJWu
2020-12-01

进制

# 关于进制

所有数字在计算机底层都以二进制形式存在。二进制形式就是01010101……

对于整数,有四种表示方式:

  • 二进制(binary)

0,1,满2进1,以0b或0B开头

  • 十进制(decimal)

0-9,满10进1。在生活中,我们用的是十进制。

  • 八进制(octal)

0-7,满8进1,以数字0开头表示。

  • 十六进制(hex)

0-A及A-F,满16进1,以0x或0X开头表示。此处的A-F不区分大小写。如:0x21AF + 1 = 0X21B0

# 进制关系表

十进制 十六进制 八进制 二进制
0 0 0 0
1 1 1 1
2 2 2 10
3 3 3 11
4 4 4 100
5 5 5 101
6 6 6 110
7 7 7 111
8 8 8 1000
9 9 11 1001
10 A 12 1010
11 B 13 1011
12 C 14 1100
13 D 15 1101
14 E 16 1110
15 F 17 1111
16 10 20 10000
17 11 21 10001

# 练习

// - 二进制(binary) 0,1,满2进1,以`0b`或`0B`开头
int num1 = 0b110; // 6

// 十进制(decimal)
int num2 = 110; // 110

// - 八进制(octal) 0-7,满8进1,以数字0开头表示。
int num3 = 0127; // 87

// - 十六进制(hex) 0-A及A-F,满16进1,以`0x`或`0X`开头表示。此处的A-F不区分大小写。
int num4 = 0x110A; // 4362
1
2
3
4
5
6
7
8
9
10
11

发现输出结果都是以十进制形式输出。

# 二进制

  • Java整数常量默认是int类型,当用二进制定义整数时,其第32位是符号位;当是long类型时,二进制默认占64位,第64位是符号位
  • 二进制的整数有如下三种形式:
    • 原码:直接将一个数值换成二进制数。最高位是符号位。
    • 负数的反码:是对原码按位取反,只是最高位(符号位)确定为1.
    • 负数的补码:其反码加1。
  • 计算机以二进制补码的形式保存所有的整数。
    • 正数的原码,反码,补码都相同
    • 负数的补码是其反码+1

# 二进制转换十进制

# 1110

比如存在一个二进制数字:1110,转换为十进制数值是多少?

  • 第一种方法:

根据进制表关系,或者去推算:

二进制 十进制
10 2
100 4
1000 8

结果是14,那么有没有更简单的方法

  • 第二种方法:

有,假设下面是内存空间

0 0 0 0 1 1 1 0
符号位 0*2^6 0**2^5 0*2^4 1*2^3 1*2^2 1*2^1 0*2^0

相加起来也是14。但是第二种方法只适用于原码。

符号位0表示整数,1表示负数。

# 1101110

比如存在一个二进制数:1101110,如何计算出十进制的实际值?

参考上个案例的第二种方法:

0 1 1 0 1 1 1 0
符号位 1*2^6 1*2^5 0*2^4 1*2^3 1*2^2 1*2^1 0*2^0

计算出结果是110。

# 10001110

那如果二进制数:10001110,十进制的实际值又是多少?

除了符号位,和上面二进制数1110(十进制14),其他都一样

  • 原码:
1 0 0 0 1 1 1 0
符号位 0*2^6 0*2^5 0*2^4 1*2^3 1*2^2 1*2^1 0*2^0

那么已经算出结果是14,因为符号位是1,所以是附属,那么最终结果是-14。

# 10111011

如果存在二进制的补码是10111011,那么它的十进制实际值是多少?

二进制的整数有如下三种形式:

  • 原码:直接将一个数值换成二进制数。最高位是符号位。
  • 负数的反码:是对原码按位取反,只是最高位(符号位)确定为1.
  • 负数的补码:其反码加1。

计算机以二进制补码的形式保存所有的整数。

  • 正数的原码,反码,补码都相同
  • 负数的补码是其反码+1

既然题目已知了补码,那么推算原码后再换算成二进制就可以了。

  • 补码
1 0 1 1 1 0 1 1
  • 反码:负数的补码是其反码+1,那么反码就是补码-1
1 0 1 1 1 0 1 0
  • 原码:反码是原码的取反,除了符号位。
1 1 0 0 0 1 0 1
1*2^6=64 1*2^2=4 1*2^0=1

那么合计结果是69,符号位是1,所以是-69。通过计算机计算-69的补码也是10111011。

# 填坑

在精度损失案例2 (opens new window)中,有一个小段代码

int i2 = 128;
byte b = (byte)i2;// -128
1
2

为什么是-128呢?来分析一下。

Java整数常量默认是int类型,当用二进制定义整数时,其第32位是符号位;

那么整数128的二进制数是:前面24个0 连上,1000 000。

1 0 0 0 0 0 0 0

那么当强转为byte时,占用8个字节空间,那么前面24个0也砍掉了,只剩下1000 0000

在二进制数中,首位是符号位,表示为负数。

那么此时变量也变成了负数,也就-128。

# 进制之间的转化

二进制以上 转为 二进制的方法是除2取余的逆。具体怎么实现等下看例子。

进制的基本转换:

  • 十进制 二进制互转
    • 二进制转成十进制:乘以2的幂数
    • 十进制转成二进制:除以2的余数
  • 二进制 八进制互转
  • 二进制 十六进制互转
  • 十进制 八进制互转
  • 十进制 十六进制互转

小技巧:多个进制转换,优先转换成二进制再转换成最终想要的,计算结果会快很多。

# 十进制转二进制

十进制数:13,求二进制数值是多少?

比如简单点的数字,自己能口算,8 + 4 + 1 = 2^3 + 2^2 + 2^0。

实际上:十进制转二进制的方法:除2取余的逆

13/2 = 6 余 1
 6/2 = 3 余 0
 3/2 = 1 余 1
 1/2 = 0 余 1
1
2
3
4

后面怎么算都是0了,补0到8位数,按反方向生成二进制数。

所以十进制数13的二进制是00001101,就写1101都行了。

# 二进制 转 八进制

二进制 转 八进制的办法是,每3个数转换一次八进制,2^3=8,二的三次幂刚好等于八,每3个数,最大数就是8。

比如:

二进制数1110 1001,转换为八进制数,值是多少?

0 1 1 1 0 1 0 0 1

先从最后面的数字看,可以把二进制数分为3个一体来转换:

// 001
1*2^0 + 0*2^1 + 0*2^2 = 1

//101
1*2^0 + 0*2^1 + 1*2^2 = 5 
    
//011 二进制数只有8位,但是前面补0不影响正数值。
1*2^0 + 1*2^1 + 0*2^2 = 3   
1
2
3
4
5
6
7
8

八进制:0-7,满8进1,以数字0开头表示。

得出结果是0351

同理

# 二进制 转 十六进制

2^4=16,每4个数字看作一体。

比如:用回刚才的二进制数:1110 1001转换为 十六进制数值是多少?

1 1 1 0 1 0 0 1
//1001
1*2^0 + 0*2^1 + 0*2^2 + 1*2^3 = 1 + 0 + 0 + 8 = 9

//1110
0*2^0 + 1*2^1 + 1*2^2 + 1*2^3 = 0 + 2 + 4 + 8 = 14 // 在十六进制中14就是E
1
2
3
4
5

16进制:0-A及A-F,满16进1,以0x或0X开头表示。此处的A-F不区分大小写。

得出结果是0XE9

# 八进制 转二进制

方法:除2取余的逆

同理,因为2^3=8,每个数字拆成3个数字。

比如八进制数为:0357,转为二进制数值是多少?

//7
7/2 = 3 余 1
3/2 = 1 余 1
1/2 = 0 余 1   
7 => 111

//5
5/2 = 2 余 1
2/2 = 1 余 0
1/2 = 0 余 1    
5 => 101

//3
3/2 = 1 余 1
1/2 = 0 余 1    
3 => 11
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

所以是1110 1111。

# 十六进制 转二进制

方法:除2取余的逆

同理,因为2^4=16,每个数字拆分4个数字

比如十六进制数为:0x3AF,转为二进制数值是多少?

//F 推算16进制>>A:10,B:11,C:12,D:13,E:14,那么F就是15,既然是最后一个数字其实全是1也是可以的。
15/2 = 7 余 1
 7/2 = 3 余 1
 3/2 = 1 余 1
 1/2 = 0 余 1    
F  => 1111

//A=10
10/2 = 5 余 0
 5/2 = 2 余 1
 2/2 = 1 余 0
 1/2 = 0 余 1    
A => 1010

//3
3/2 = 1 余 1
1/2 = 0 余 1    
3 => 11
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

所以结果是11 1010 1111 。

# Java 二进制API

在将来的java开发中如果需要用到二进制,可以找到Integer.class中的方法,使用API直接转换

  • 二进制:toBinaryString
  • 八进制:toOctalString
  • 十六进制:toHexString

这里就不做展开了。

至此,已经掌握了各种进制的转换,以及弄清楚原码,反码,补码的概念。

帮我改善此页面 (opens new window)
#二进制#十进制#八进制#十六进制#原码#反码#补码
上次更新: 2020/12/18, 12:50:58
字符串类型 String
运算符

← 字符串类型 String 运算符→

最近更新
01
zabbix学习笔记二
02-28
02
zabbix学习笔记一
02-10
03
Linux访问不了github
12-08
更多文章>
Theme by Vdoing | Copyright © 2020-2022 Saul.J.Wu | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式