0%

Java 理解数据背后的二进制(一):二进制基础

1. 负整数的二进制怎样表示

  • 二进制使用最高位表示符号位,用 1 表示负数,用 0 表示正数
  • 但负数表示不是简单地将最高位变为 1。负数的二进制表示就是对应的正数的补码
  • 补码 = 原码取反 + 1

2. 给定一个负数的二进制表示,怎样知道它的十进制。试写出 10010010 的十进制表示

  1. 可以采用相同的补码运算,类似于十进制中的负负得正
  2. 对于 10010010首先得到正数:对 10010010 做补码运算。首先取反,变为 01101101;然后加 1,变为 01101110
  3. 其次转换为十进制01101110 的十进制值为 110,所以原值就是 -110

3. 负整数的二进制为什么采用对应正数的补码这种奇怪的表示形式

  • 因为计算机只能做加法,1 - 1 其实就是 1 + (-1)
  • 只有这种形式,计算机才能实现正确的加减法。如果用原码表示,计算结果是不对的
  • 虽然看上去比较奇怪和难以理解,但这种表示其实是非常严谨和正确

4. 为什么正数的运算结果可能出现负数

  • 计算结果超出表示范围的时候,最高位往往是 1,然后就会被看做负数

5. Java 中怎样表示二进制位或二进制常量

  • Java 7 之前不支持直接写二进制常量。比如,想写二进制形式的 11001,Java 7 之前不能直接写,可以在前面补 0,补足 8 位,为 00011001,然后用 16 进制表示,即 0x19
  • Java 7 开始支持二进制常量,在前面加 0b0B 即可。比如:int a = 0b11001;

6. Java 中位运算都有哪些

  • 移位运算
    1. 左移:操作符为 <<
    2. 无符号右移:操作符为 >>>
    3. 有符号右移:操作符为 >>
  • 逻辑运算
    1. 按位与&
    2. 按位或|
    3. 按位取反~
    4. 按位异或^

7. 计算机中很多数不能精确表示和计算的原因是

  • 本质原因是计算机根本就不能精确地表示很多数
  • 计算机的底层是二进制,而二进制只能表示那些可以表述为 2 的多少次方和的数,所以很多数只能无限接近但不能精确表示

8. 为什么计算机中不能用我们熟悉的十进制

  • 计算机的底层使用的电子元器件只能表示为两个状态,通常是低压和高压,对应 0 和 1,使用二进制容易基于这些电子元器件构建硬件设备和进行运算
  • 如果非要使用十进制,则这些硬件就会复杂很多,并且效率低下

9. 下面的代码:System.out.println(0.1f + 0.1f);System.out.println(0.1f * 0.1f); 为什么小数的加法结果正确而乘法却不精确

  • 第一行输出 0.2,第二行输出 0.010000001。0.2 看似是准确的,其实这只是 Java 语言给我们造成的假象
  • 真实计算结果其实也是不精确的,但是由于结果和 0.2 足够接近,在输出的时候,Java 选择输出 0.2 这个看上去非常精简的数字,而不是一个中间有很多 0 的小数
  • 在误差足够小的时候,结果看上去是精确的,但不精确其实才是常态

10. 实际开发中,面对计算不精确的情况,作为开发者如何解决这个问题

  • 大部分情况下,我们不需要那么高的精度,可以四舍五入,或者在输出的时候只保留固定个数的小数位
  • 如果真的需要比较高的精度,有两种方法:
    1. 一种方法是将小数转化为整数进行运算,运算结果再转化为小数
    2. 另一种方法是使用十进制的数据类型,这个并没有统一的规范。在 Java 中是 BigDecimal,运算更准确,但效率比较低

11. 怎么理解浮点数

  • 浮点数其实就是小数,但在概念上比小数更加严谨
  • 这是因为小数的二进制表示中,表示那个小数点的时候,点不是固定的,而是浮动的

12. 十进制有科学计数法,二进制怎样表示小数

  • 和十进制的科学计数法类似:m *(2 ^ e)m 称为尾数,e 称为指数

13. NaN 什么意思

  • 几乎所有的硬件和编程语言表示小数的二进制格式都是一样的。这种格式是一个标准,叫做 IEEE 754 标准,它定义了两种格式,一种是 32 位的,对应于 Java 的 float,一种是 64 位的,对应于 Java 的 double
  • 在两种格式中,除了表示正常的数,IEEE 754 标准还规定了一些特殊的二进制形式表示一些特殊的值,比如负无穷、正无穷、0、NaN
  • NaN 表示非数值,比如 0 乘以无穷大
-------------------- 本文结束感谢您的阅读 --------------------