考虑以下 Java 代码:
public class Program {
public static void main(String args[]) {
double number = Double.MAX_VALUE;
String formattedNumber = String.format("%f", number);
System.out.println(formattedNumber);
}
}
1797693134862315700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000000000000000000000.000000
考虑等效的 C# 代码:
public class Program
{
public static void Main(string[] args)
{
double value = double.MaxValue;
Console.WriteLine(value.ToString("F"));
}
}
1797693134862315708145274237317043567980705675258449965989174768031572607800285387605895586327668781715404589535143824 642343213268894641827684675467035375169860499105765512820762454900903893289440758685084551339423045832369032229481658085593 32123348274797826204144723168738177180919299881250404026184124858368.000
鉴于
Double
的最大值为1.7976931348623157E+308,据我所知,Java输出是正确的;即浮点值实际上代表一个整数,其中前 17 位数字是 17976931348623157,后面是 292 个零。
注意:在 C# 中将
double
转换为 BigInteger
会产生相同的结果:
BigInteger value = (BigInteger)double.MaxValue;
Console.WriteLine(value);
1797693134862315708145274237317043567980705675258449965989174768031572607800285387605895586327668781715404589535143824 642343213268894641827684675467035375169860499105765512820762454900903893289440758685084551339423045832369032229481658085593 32123348274797826204144723168738177180919299881250404026184124858368
问题
鉴于Double的最大值为1.7976931348623157E+308…
这是不正确的。
Double
使用的格式是 IEEE 754-2019 标准中指定的 binary64 或“双精度”格式。在这种格式中,有限数表示为±f•2e,其中f,表示的小数部分,是由二进制数字表示的数字,前一位数字(0或1)小数点及其后的 52 位和指数 e 是 [−1022, 1023] 中的整数。所以最大可表示的有限值是 +1.111111111111111111111111111111111111111111111111111112•21023,等于 +(21−2−52)•21023 = 21024−2971,其中正好是 179,769,313,486,231,570,814,527,423,731,704,356,798,070,567,525,844,996,598,917,476,803,157,260,780,028,538,760,589,558 ,632,766,878,171,540,458,953,514,382,464,234,321,326,889,464,182,768,467,546,703,537,516,986,049,910,576,551,282,076,245,49 0,090,389,328,944,075,868,508,455,133,942,304,583,236,903,222,948,165,808,559,332,123,348,274,797,826,204,144,723,168,738,1 77,180,919,299,881,250,404,026,184,124,858,368,所以 C# 输出是正确的。
Java 输出省略了有效数字并隐藏了真实值。这是因为 Java 规范规定,对于默认格式 “必须至少有一个数字来表示小数部分,除此之外,还有许多数字,但只是唯一区分参数值所需的数字”
double
类型的相邻值。”