ser*_*0ne 2 c# java double ieee-754
考虑以下 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);
}
}
Run Code Online (Sandbox Code Playgroud)
179769313486231570000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000.000000
考虑等效的 C# 代码:
public class Program
{
public static void Main(string[] args)
{
double value = double.MaxValue;
Console.WriteLine(value.ToString("F"));
}
}
Run Code Online (Sandbox Code Playgroud)
179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234 32132688946418276846754670353751698604991057655128207624549009038932894407586850845513394230458323690322294816580855933212334 8274797826204144723168738177180919299881250404026184124858368.000
鉴于 的最大值Double为 1.7976931348623157E+308,据我所知,Java 输出是正确的;即浮点值实际上表示一个整数,其中前 17 位数字为 17976931348623157,后跟 292 个零。
注意:在 C# 中转换double为BigInteger会产生相同的结果:
BigInteger value = (BigInteger)double.MaxValue;
Console.WriteLine(value);
Run Code Online (Sandbox Code Playgroud)
179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234 32132688946418276846754670353751698604991057655128207624549009038932894407586850845513394230458323690322294816580855933212334 8274797826204144723168738177180919299881250404026184124858368
问题
\n\n假设 Double 的最大值为 1.7976931348623157E+308\xe2\x80\xa6
\n
这是不正确的。使用的格式Double是IEEE 754-2019标准中指定的binary64或\xe2\x80\x9c双精度\xe2\x80\x9d格式。在此格式中,有限数表示为 \xc2\xb1 f \xe2\x80\xa22 e,其中f是表示形式的小数部分,是由前面带有一位数字(0 或 1)的二进制数字表示的数字小数点及其后的 52 位和指数e是 [\xe2\x88\x921022, 1023] 中的整数。因此,最大可表示的有限值为 +1.11111111111111111111111111111111111111111111111111111 2 \xe2\x80\xa22 1023,等于 +(2 1 \ xe2\x88\x922 \xe2\x88\x9252 )\x e2\x80\xa22 1023 = 2 1024 \xe2\ x88\x922 971 , which is exactly 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,490,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,177,180,919,299,881,250,404,026,184,124,858,368, so the C# output is correct.
Java 输出省略有效数字并隐藏真实值。这是因为 Java 规范规定,对于默认格式\xe2\x80\x9c ,必须至少有一位数字来表示小数部分,除此之外,还有尽可能多的数字来唯一区分来自类型double.\xe2\x80\x9d的相邻值的参数值