JavaSE 基础 (5) 进制

Debug 介绍与操作流程

Debug 概述

Debug: 是供程序员使用的程序调试工具,它可以用于 查看程序执行流程,也可以用于追踪程序执行过程来 调试程序


Debug 操作流程

Debug 调试,又被称为断点调试,断点其实是一个标记,告诉 Debug 从标记的地方开始查看
① 如何加断点
② 如何运行加了断点的程序
③ 看哪里
④ 点哪里
⑤ 如何删除断点


如何加断点

选择要设置断点的代码行,在行号的区域后面单击鼠标左键即可。

/images/java/JavaSE 基础 (5) 进制/1.png
(图1)

如何运行加了断点的程序

在代码区域右键 Debug 执行

/images/java/JavaSE 基础 (5) 进制/2.png
(图2)

看哪里

看 Debugger 窗口

/images/java/JavaSE 基础 (5) 进制/3.png
(图3)

看 Console 窗口

/images/java/JavaSE 基础 (5) 进制/4.png
(图4)

点哪里

点 Step Into(F7) 这个箭头,也可以直接按 F7

/images/java/JavaSE 基础 (5) 进制/5.png
(图5)

点 Stop 结束

/images/java/JavaSE 基础 (5) 进制/6.png
(图6)

如何删除断点

选择要删除的断点,单击鼠标左键即可。

/images/java/JavaSE 基础 (5) 进制/7.png
(图7)

如果是多个断点,可以每一个再点击一次。也可以一次性全部删除。

/images/java/JavaSE 基础 (5) 进制/8.png
(图8)

step over 和 strp info 区别

在 Idea 中,Step Over 和 Step Into 是调试器(Debugger)中的两种单步执行模式。

Step Over(跳过)是指执行当前行代码,如果当前行代码是一个方法调用,则直接运行完这个方法,得到方法的返回值,而不会进入到这个方法。

Step Into(进入)是指执行当前行代码,如果当前行代码是一个方法调用,则进入该方法,然后继续单步执行。它与 Step Over 的区别在于,如果当前行是一个方法调用,Step Into 会进入到这个方法继续单步执行,而 Step Over 则是直接将整个方法执行完。

Debug 查看方法参数传递

/images/java/JavaSE 基础 (5) 进制/9.png
(图9)

在 debugger 中, 我们可以看到 change 方法在 main 方法的上面, 属于压栈操作

通过方法运行结果可知, 在 change 方法中, 形式参数 number 的值原本为 number = 100, 我们将 number 的值修改为 number = 200, 但是修改的只是 change 方法中number的值, 并不是 main 方法中 number 的值, 所以 调用change方法后:100

技巧

  在 Java 和许多其他编程语言中,基本数据类型(如int、float、boolean等)是按值传递的,这意味着当你把一个基本数据类型作为参数传递给一个方法时,实际上是传递了这个值的副本。
  然而,对于引用数据类型(如对象、数组等),情况就不同了。当你传递一个引用数据类型给一个方法时,你实际上是传递了这个对象(或对象在内存中的地址)的引用。所以,在方法内部,你可以通过这个引用来修改对象的状态。

进制的介绍与书写格式

进制介绍

进制:指进位制,是人们规定的一种进位方式

表示某一位置上的数,运算时是逢X进一位。

十进制是逢十进一,二进制就是逢二进一,八进制是逢八进一

常见进制:二进制,八进制,十进制,十六进制


为什么要学习进制?

原因:计算机数据在底层运算的时候,都是以 二进制形式

也有数据是以八进制、十进制、或者十六进制进行存储或运算,了解不同的进制,便于我们对 数据的运算过程 理解的更加深刻。


分类

  • 2 进制数据: 以 0b 作为开头, b 大小写都可以。
  • 8 进制数据: 以 0 作为开头
  • 10 进制数据: 正常书写, Java 中,数值默认都是 10 进制,不需要加任何修饰。
  • 16 进制数据: 以 0x 作为开头, x 大小写都可以。

注意:以上内容是 jdk7 版本之后才被支持。


十进制

/images/java/JavaSE 基础 (5) 进制/10.png
(图10)

二进制

介绍:二进制数据是用 0 和 1 两个数码来表示。例如:0101000
进位规侧则是 “逢二进一”,借位规则是 “借一当二”。

二进制计算:0011 + 1

/images/java/JavaSE 基础 (5) 进制/11.png
(图11)

二进制计算:0010 - 1

/images/java/JavaSE 基础 (5) 进制/12.png
(图12)

对程序员计算器的讲解

/images/java/JavaSE 基础 (5) 进制/13.png
(图13)

八进制和十六进制

  • 八进制介绍:采用 0, 1, 2, 3, 4, 5, 6, 7 八个数字,逢八进 1
  • 十六进制介绍:用数字 09 和字母 AF (或 a~f)表示,其中:A~F 表示 10~15,这些称作十六进制。
    [0][1][2][3][4][5][6][7][8][9][a][b][c][d][e][f]

任意进制到十进制的转换

在线进制转换的工具:https://tool.lu/hexconvert/


进制转换

  • 二进制十进制 的转换
  • 公式:系数 * 基数的权次幂相加
  • 系数:每一【位】上的数
  • 基数:几进制,就是几
  • 权:从数值的右侧,以 0 开始,逐个 +1 增加

二进制转十进制:权相加法

/images/java/JavaSE 基础 (5) 进制/14.png
(图14)

  • 十六进制十进制 的转换
  • 公式:系数 * 基数的权次幂相加

  • 总结: 任意进制十进制 的转换
  • 公式:系数 * 基数的权次幂相加

十进制到任意进制的转换

  • 十进制二进制 的转换
  • 公式:除基取余 ( 除 2 取余,逆序排列 )
    使用源数据,不断的 除以基数 (几进制,基数就是几) 得到余数,直到商为0,再 将余数倒着拼起来 即可。

需求:将十进制数字 11,转换为二进制。

实现方式:源数据为 11,使用 11 不断的除以基数,也就是 2,直到商为 0。

/images/java/JavaSE 基础 (5) 进制/15.png
(图15)

  • 十进制十六进制 的转换
  • 公式:除基取余
    使用源数据,不断的除以基数(几进制,基数就是几)得到余数,直到商为 0,再将余数倒着拼起来即可。

需求:将十进制数字 60,转换为十六进制。
实现方式:源数据为 60,使用 60 不断的除以基数,也就是16,直到商为0。

/images/java/JavaSE 基础 (5) 进制/16.png
(图16)

注意:十六进制中,12 使用 C 进行表示
结果:3C

1
2
3
4
5
6
public static void main(String[] rgs){
	int a = 10_0000_0000;
	System.out.println(a);
}

在Java和许多其他编程语言中"_"下划线在数字之间并`不影响变量的值`。它主要用于`提高数字的可读性`,特别是在数字很大或者很多的情况下

快速进制转换法

8421 码

8421 码又称 BCD 码,是 BCD 代码中最常用的一种

BCD:(Binary-Coded Decimal) 二进制码十进制数

在这种编码方式中,每一位二进制值的1都是代表一个固定数值,把每一位的 1 代表的十进制数加起来

得到的结果就是它所代表的十进制数。


二进制快速转十进制

/images/java/JavaSE 基础 (5) 进制/17.png
(图17)

公式:系数 * 基数的权次幂相加

/images/java/JavaSE 基础 (5) 进制/18.png
(图18)
/images/java/JavaSE 基础 (5) 进制/19.png
(图19)

可将 2 进制数值直接套入其中,0 所对应的值不取,1 所对应的值取出并相加

例如:二进制 0b1101

8+4+1=13

二进制 0b1101, 转十进制后,结果为 13


二进制快速转八进制

八进制:将 三个二进制位看为一组,再进行转换

原因:八进制逢八进一,三个二进制位最多可以表示 111,也就是数值 7,如果出现第四位,就超范围了

需求:将 60 的二进制 0b111100 转换为八进制

/images/java/JavaSE 基础 (5) 进制/20.png
(图20)

二进制快速转十六进制

十六进制:将 四个二进制位看为一组,再进行转换

原因:十六进制逢十六进一,四个二进制位最多可以表示 1111,也就是数值 15,如果出现第五位,就超范围了

需求:将 60 的二进制 0b111100 转换为十六进制

/images/java/JavaSE 基础 (5) 进制/21.png
(图21)

原码反码补码

为什么要学习原码、反码、补码?

/images/java/JavaSE 基础 (5) 进制/22.png
(图22)

130 超过 byte 的范围了, 虽然我们可以通过强制转换使他不报错, 但是会出现精度损失, 有些人就猜测打印的值是 127, 因为 byte 最大值就是 127, 但是结果不是这样的

运行结果:-126


原码反码补码

注意:计算机中的数据,都是以二进制补码的形式在运算,而补码则是通过反码和原码推算出来的。


原码(可直观看出数据大小) 就是二进制定点表示法,即最高位为符号位,[0]表示正,[1]表示负,其余位表示数值的大小。
通过一个字节表示 +7 和 -7,代码:byte b1 = 7; byte b2 = -7;
一个字节等于 8 个比特位,也就是 8 个二进制位,第一位是符号位
0000 0111
1000 0111


反码 (只是为了原码和补码之间做转换, 所提供的一个中间桥梁, 它是用来做服务的)
正数的反码与其原码相同;负数的反码是对其原码逐位取反,但符号位除外


补码(数据以该状态进行运算
正数的补码与其原码相同;负数的补码是在其反码的基础上加 1。


原码: 数据
反码: 数据
补码:运算 数据


正数的原反补都是相同的
负数的【反码】,是根据 【原码】取反(0 变 1,1 变 0) 得到的(符号位不变)
负数的【补码】,是根据 【反码】的末尾 +1,得到的


求 -7 的补码

原码:1(符号位) 0000111 –→ 符号位不变,0 变 1,1 变 0

反码:1(符号位) 1111000 –→ 反码末尾 + 1,求补码

补码:1(符号位) 1111001

问题:根据原码能慢慢推导补码,根据补码能否反向推导原码?


1
2
byte b = (byte) 130;
System.out.println(b);

① 整数 130:默认为 int,int 占用 4 个字节,也就是 4 组 8 个二进制位

00000000 00000000 00000000 10000010

② 强转到byte:4个字节,强制转换为1个字节,就是砍掉前3组8位

10000010

130 是正数, 所以他的原码、反码、补码都一样, 都是 00000000 00000000 00000000 10000010 , 然后因为强制转换, 截取为一个字节, 剩下的为 10000010 , 在计算机中参与运算的都是补码, 此时 10000010 就是补码

③ 根据运算后的补码,反向推原码

/images/java/JavaSE 基础 (5) 进制/23.png
(图23)

④ 使用 8421 码开始计算

/images/java/JavaSE 基础 (5) 进制/24.png
(图24)

0%