这个问题在这里已经有了答案:
10年前关闭。
1) 有人可以向我解释 MIN_NORMAL 和 MIN_VALUE 之间的区别是什么吗?
System.out.println(Float.MIN_NORMAL);
System.out.println(Float.MIN_VALUE);
2)另外,为什么还是打印1.0?
float f = Float.MIN_NORMAL + 1.0f;
System.out.println(f);
double d = Float.MIN_NORMAL + 1.0f;
System.out.println(d);
输出:
1.17549435E-38
1.4E-45
1.0
1.0
最佳答案
第一个问题的答案在副本中。
第二个问题的答案是:
Floats 和 Doubles 都没有无限精度。您可以很方便地认为它们的精度约为 16 位。任何超过它,你都会有舍入错误和截断。
因此,由于截断了额外的精度,1.0e0 + 1e-38 将缺乏精度,除了以 1.0e0 结尾之外,无法执行任何操作。
真的,就像答案的其余部分一样,它需要了解 IEEE 格式的浮点数实际上是如何以二进制形式相加的。基本思想是二进制浮点数的非符号和指数部分在 CPU 上的 IEEE-754 单元中移位(在 Intel 上为 80 位宽,这意味着总是在结尾处进行截断)计算)来表示它的实数。在十进制中,这看起来像这样:
数字:1 234567890123456
值:1.0000000000000000000000000000...0000
值:0.0000000000000000000000000000...0001
添加处理后,实际是:
数字:1 234567890123456
值:1.0000000000000000000000000000...0001
因此,请记住,该值会在 16 位标记附近截断(以十进制表示,它恰好是 32 位浮点数中的 22 个二进制数字,以及 64 位 double 数中的 51 个二进制数字,忽略了非常重要的事实,即前导数1 被移位(相对于指数)并假设(有效地将 23 个二进制数字压缩为 32 位的 22 和 64 位的 52 到 51);这是一个非常有趣的点,但你应该阅读更详细的例子,例如 here 了解这些细节)。
截断:
数字:1 234567890123456
值(value):1.00000000000000000000
请注意,非常小的小数部分被截断,从而留下 1。
这是一个很好的页面,每当我在考虑内存中的实际表示时遇到问题时,我都会使用它: Decimal to 32-bit IEEE-754 format 。在该站点中,也有 64 位链接和反向链接。
关于java - Float.MIN_VALUE 和 Float.MIN_NORMAL 的区别?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/5852611/