Java 基本类型的各种运算,你真的了解了么?

Java 基本类型的各种运算,你真的了解了么?

💡 原文中文,约7300字,阅读约需18分钟。
📝

内容提要

本文讲解Java基本类型运算:整数运算包括比较、算术、移位等操作符及类型转换,重点剖析原码、反码、补码原理,解释int转byte精度丢失原因;浮点数遵循IEEE 754标准,以1.0-0.9为例说明其无法精确表示;最后介绍布尔逻辑与三元运算符。

🔎

延伸解读

补码:计算机整数运算的基石

文章详细解释了原码、反码和补码的演进。原码直观但无法直接进行减法运算;反码解决了部分问题,却导致0有两种表示(+0和-0);补码通过负数取反加一,使0只有一种表示,并让符号位参与运算,将减法转换为加法,简化了硬件设计。因此,现代计算机普遍采用补码存储整数。理解补码是解释类型转换精度丢失等问题的关键。

int转byte精度丢失的根源

文章以int转byte为例,展示了精度丢失的原因:Java截取int的低8位存入byte。若原int值为129,其补码低8位为1000 0001,作为byte的补码,转换为原码后得到-127。这解释了为何强制转换后输出-127而非129。读者需注意,高精度转低精度可能因截断而改变数值,使用时需显式转换并确认结果是否符合预期。

浮点数运算:为何1.0-0.9不等于0.1

浮点数遵循IEEE 754标准,采用符号位、阶码和尾数表示。由于二进制无法精确表示某些十进制小数,如0.9,运算时需对阶、求和、规格化和舍入,导致精度损失。文章以1.0-0.9为例,逐步演示了计算过程,最终结果为0.100000024。这提醒开发者,浮点数运算可能存在微小误差,直接使用==比较浮点数相等性可能导致错误。

整数与浮点数运算的差异

整数运算支持位操作(如移位、按位与等),而浮点数只能进行加减乘除。浮点数表示范围更大,32位float的精度甚至超过64位long,但无法精确表示所有小数。整数运算中,byte、char、short参与运算会自动提升为int,但+=和++不会。这些差异要求开发者在混合运算时注意类型转换规则,避免意外结果。

❓

Q&A

Java 中 int 转 byte 为什么会丢失精度?

因为 int 是 32 位,byte 是 8 位,转换时 Java 会截取 int 的后 8 位存入 byte。例如 int 129 的补码后 8 位是 1000 0001,作为 byte 的补码,转成原码是 1111 1111,即 -127,所以输出 -127 而不是 129。

为什么 1.0 - 0.9 在 Java 中不等于 0.1?

因为浮点数遵循 IEEE 754 标准,无法精确表示 0.9 等十进制小数。计算 1.0 - 0.9 时,经过对阶、尾数求和、规格化和舍入,最终结果是 0.100000024,而不是精确的 0.1。

Java 中原码、反码和补码有什么区别?

原码是符号位加二进制数值,简单直观但不能直接参与运算;反码正数不变,负数符号位不变、数值位取反,解决了减法问题但 0 有两种表示;补码正数不变,负数反码加一,0 只有一种表示,且符号位可参与运算,因此计算机用补码存储数据。

Java 中哪些情况会发生隐式类型转换?

低精度类型转高精度类型时,Java 会自动进行隐式转换,不会丢失精度。例如 byte、char、short 参与运算时会自动转为 int,多种类型混合运算时自动转为精度最大的类型,但布尔类型不能参与转换。

Java 浮点数在计算机中是如何存储的?

Java 浮点数遵循 IEEE 754 标准,以科学计数法为基础。32 位 float 分为三部分:1 位符号位、8 位阶码位(存储移码,实际指数需减去 127)、23 位尾数位(存储有效数字,省略整数部分的 1)。double 双精度则是 1 位符号位、11 位阶码、52 位尾数。

Java 中三元运算符怎么用?

三元运算符格式为:布尔表达式 ? 值1 : 值2。如果布尔表达式为 true,返回值1,否则返回值2。例如 int b = a > 10 ? 10 : a,当 a 为 99 时 b 为 10,当 a 为 6 时 b 为 6。

🏷️

标签

➡️

继续阅读