Float.MAX\_VALUE + 1 = Float.MAX\_VALUE??
=========================================
前置:JAVA数据类型基础知识
===============
数据类型
数据类型定义与取值范围
位溢出
在 Java 中,数据类型有固定的大小,并且它们的整数表示是使用补码(two’s complement)形式。这种表示形式对整数进行加法和减法时会导致溢出(overflow)。溢出时,结果不会引发错误或异常,而是以一种特定的方式“环绕”到最小或最大可能值。
正题
好了,有了上面的知识,便可以开始我们今天的正题了,先来看看下图
乍一看,是不是毫无规律,Integer
和Long
加完1后变MIN_VALUE
,Short
却没有位溢出变MIN_VALUE
,接下来的Float
和Double
加1后并没有变MIN_VALUE
,也没有变化(当然这里加的数太小,不足以论证没有变化,我们下文再详解)
Integer
Integer
的位溢相信大家都熟悉,但这里还是不厌其烦的解释一下
Integer.MAX_VALUE
是 2147483647
,这是一个 32 位有符号整数的最大值。二进制表示如下:
01111111 11111111 11111111 11111111
当 +1 时,发生溢出,导致最左边的一位(符号位)变为 1:
10000000 00000000 00000000 00000000
在补码表示中,这个值是 -2147483648
,即 Integer.MIN_VALUE
。所以 Integer.MAX_VALUE + 1
变成了负数 -2147483648
。
但是,如果明确指明’1’类型Long
(即’1L’),结果则会变为2147483648
Long
Long
与Integer
同理
Long.MAX_VALUE
是 9223372036854775807
,这是一个 64 位有符号整数的最大值。其二进制表示如下:
01111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111
当在这个值上加 1 时,发生溢出,导致最左边的一位(符号位)变为 1:
10000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
在补码表示中,这个值是 -9223372036854775808
,即 Long.MIN_VALUE
。所以 Long.MAX_VALUE + 1
变成了负数 -9223372036854775808
。
Short
Short.MAX_VALUE
是 32767
,这是一个 16 位有符号整数的最大值。二进制表示如下:
01111111 11111111
当你加 1 时,发生溢出:
10000000 00000000
在补码表示中,这个值是 -32768
,即 Short.MIN_VALUE
。
然而,在 Java 中,short
类型的操作会自动提升为 int
类型进行计算,因此 Short.MAX_VALUE + 1
实际上是一个 int
计算:
32767 + 1 = 32768
这个结果在 int
类型范围内,所以不会发生溢出,结果是正数 32768
。
Float
Float.MAX_VALUE
是 3.4028235e+38,这是最大的正浮点数
Float.MIN_VALUE
是 1.4e-45,这是最小的正浮点数(靠近 0,但不是 0,是不是很容易被上面带坏以为是负值🤐)
浮点数的溢出行为
为什么 Float.MAX_VALUE + 1
不会变成 Float.MIN_VALUE
Float.MAX_VALUE
加任何数时,由于 Float.MAX_VALUE
已经是最大值,结果会超出 float
类型的表示范围。因此,结果将是正无穷大(Float.POSITIVE_INFINITY
),而不是 Float.MIN_VALUE
Float.MIN_VALUE
是接近 0 的最小正数,而不是表示溢出到最小数的特殊值。- 浮点数运算遵循
IEEE 754
标准,正溢出会导致结果变为无穷大,而不是循环到最小值。
当浮点数超过其可表示的范围时,会发生溢出
- 正溢出:当一个浮点数超过
Float.MAX_VALUE
,结果将是正无穷大(Float.POSITIVE_INFINITY
)。 - 负溢出:当一个负浮点数的绝对值超过
Float.MAX_VALUE
的负值,结果将是负无穷大(Float.NEGATIVE_INFINITY
)。
Double
Double
与Float
同理
Double.MAX_VALUE
是 1.7976931348623157e+308
Double.MIN_VALUE
是 4.9e-324
双精度浮点数的溢出行为
正溢出与负溢出
题外:Java 中的数据类型转型上升
什么是数据类型转型上升?
数据类型转型上升(Numeric Promotion)指的是在算术运算中,较小的数据类型会自动提升到较大或更通用的数据类型。Java 的数值提升规则如下:
- 整型提升:在算术运算中,
byte
、short
和char
会被提升为int
类型。如果一个操作数是long
,另一个操作数也会提升为long
。 - 浮点提升:如果一个操作数是
float
,另一个操作数会提升为float
。如果一个操作数是double
,另一个操作数会提升为double
。
为什么会有数据类型转型上升?
在 Java 编程中,数据类型的转型(或称类型提升)是一个常见且重要的概念。理解它的原理和应用对于编写高效且正确的代码至关重要。在这篇文章中,我们将深入探讨 Java 中的数据类型转型上升,解释其背后的原理,并通过示例展示其实际应用。
这种自动提升机制主要是为了以下原因:
- 避免溢出和信息丢失:较小的数据类型在进行算术运算时,如果不提升为
int
或更高类型,可能会由于其有限的表示范围而导致溢出或信息丢失。例如,byte
类型的范围是 -128 到 127,如果两个byte
值相加结果超出这个范围,会导致错误的结果。 - 简化处理逻辑:如果所有算术运算都在
int
类型及以上进行,可以简化 JVM 的实现和优化逻辑,从而提高运行效率和代码的可移植性。
不同数据类型在算术运算中的提升行为:
public class NumericPromotionExample {
public static void main(String[] args) {
short a = 32767; // Short.MAX_VALUE
short b = 1;
int result = a + b;
System.out.println("Result: " + result); // 输出 "Result: 32768"
}
}
在上面的代码中:
a
和b
都是short
类型。- 在
a + b
运算中,a
和b
都会被自动提升为int
类型。 - 结果
32768
是int
类型,因为short
类型无法表示32768
(超出了short
的范围)。
int
类型的特殊情况
在 Java 中,int
类型是 32 位的整数类型,已经是 Java 中最常用的整数类型之一。为了保持性能和简化处理,int
类型在算术运算中不会自动提升到更高的类型(如 long
或 double
),除非有混合类型的操作数。例如:
- 如果一个操作数是
long
,那么int
操作数会被提升为long
。 - 如果一个操作数是
float
,那么int
操作数会被提升为float
。 - 如果一个操作数是
double
,那么int
操作数会被提升为double
。
int
在不同操作数类型中的提升行为:
public class NumericPromotionExample {
public static void main(String[] args) {
int intVal = 2147483647; // Integer.MAX_VALUE
long longVal = 10L;
float floatVal = 1.5f;
double doubleVal = 2.5;
// int + long -> long
long result1 = intVal + longVal; // 自动提升为 long
System.out.println("int + long -> long: " + result1);
// int + float -> float
float result2 = intVal + floatVal; // 自动提升为 float
System.out.println("int + float -> float: " + result2);
// int + double -> double
double result3 = intVal + doubleVal; // 自动提升为 double
System.out.println("int + double -> double: " + result3);
// 溢出示例
int overflowResult = intVal + 1; // 不会提升,导致溢出
System.out.println("Integer.MAX_VALUE + 1: " + overflow
原文链接: https://juejin.cn/post/7374045077452423195
文章收集整理于网络,请勿商用,仅供个人学习使用,如有侵权,请联系作者删除,如若转载,请注明出处:http://www.cxyroad.com/17296.html