IEEE 754浮点数是离散的。
public class MyTest2 {
public static void main(String[] args) {
//about 1.00000001490116119384765625E-1 in IEEE-754
float f = 0.1f;
//about 1.00000000000000005551115123126E-1 in IEEE-754
double d = 0.1d;
System.out.println(String.format("double 0.1= %.30f", d));
System.out.println(String.format("float 0.1 = %.15f", f));
System.out.println(d+"");
}
}
查看此代码在IdeOne上的实时运行。通用域名格式。在JDK8中运行时,输出是
double 0.1= 0.100000000000000000000000000000
float 0.1 = 0.100000001490116
0.1
浮点值按预期打印。我预计双倍值0.1d会像1.000000000000000055511151231260一样打印。为什么它在分数部分打印所有零?
如果我把双变量d转换成字符串,它会输出0.1。
System.out.println(d+"");
java如何将0.1d(大约为1.0000000 149011938476565E-1)的neartest浮点值转换为精确的0.1?
如果你看到java源代码,你会发现
System.out.println(d+"");
将使用以下内容:
Double.toString(d)
这反过来将调用
FloatingDecimal.toJavaFormatString(d)
字符串。格式
使用其他机制。这就是为什么你会看到这种行为。
参考文献:
Java规范要求这种不完美的值显示。f
格式产生的有效位数仅与双精度格式产生的有效位数相同。toString(double)
方法将生成零,然后mindlessy追加零以达到要求的精度。
根据文档,对于f
格式,如果精度超过小数点后的位数,则为双精度。toString(double)
将产生,然后“可以添加零以达到精度”这并没有说明这些零附加到了什么。据推测,它们被附加到Double的字符串中。toString(double)
会产生。
Double的文档。toString(double)
表示,它会生成“尽可能多的数字,但只会产生尽可能多的数字,以便唯一地将参数值与类型为double
的相邻值区分开来”我在这里进一步讨论这个问题。对于0.10000000000000055115123125782702118158340451015625,Double。toString(双精度)
产生“0.1”。(相邻的值0.099999999999167332731531132594682276248931884765625和0.100000000000001942890293094023945741355419158935546875都比0.10000000000000055115123125782702118158340411015625远,它们的格式为“0.09999999999999999999”和“0.100000000000002”,因此为“0.1”用于唯一区分0.100000000000000551151231257827021181583404540105625与其邻居。)
因此,系统。出来println(String.format(“double 0.1=%.30f”,d))
以double中的“0.1”开头。toString(双精度)
并附加29个零。
同样,如果将d
更改为0.099999999999167332731531132594682276248931884765625,String。format
生成“0.099999999999999000000000000”-它将转换为字符串
结果并附加零。对于0.100000000000001942890293094023945741355419158935546875,它产生了“0.10000000000000000200000000000000”。
这符合规格。指定的行为无法正确呈现真实值,因此我认为该规范存在缺陷。
顺便说一句,无论请求的精度是大于还是小于双精度的位数,Java规范都很麻烦。toString(double)
会产生。在请求权限较小的情况下,Java规范需要双舍入,这可能会增加错误。
什么是“精度”?使用float和double时,单和双有什么区别?“单精度32位IEEE 754浮点”“双精度64位IEEE 754浮点”是什么意思?
我理解二进制数的理论,所以双精度数的运算是不精确的。但是,在java中,我不知道为什么“(double)65 / 100”是0.65,这在十进制数上是完全正确的,除了0.6500000000004。
我有一系列这样的数据:100 Mbps,200 Mbps,512 Kbps,256 Kbps,100 Mbps, 我需要标准化所有必须在“Mbps”单元中的数据。我正在使用Jaspersoft的ETL软件,该软件允许输入表达式来转换数据。每个数据将被分成两个变量,一个用于存储单位(speedunit),另一个用于存储值(speedvalue),类型为Double。现在,我使用以下表达式: 问题是,
问题内容: 我有一个类似的双精度数字,我需要把它显示为。 如何用Java做到这一点? 问题答案: 结果是 这是我最接近的。
问题内容: 我正在编写一个简单的Java程序。我需要从输入中获取一个字符串并将其分为两部分:1-double 2-string。然后,我需要对double进行简单的计算,并将结果发送到具有特定精度的输出(4)。它工作正常,但是当输入为0时出现问题,则不能正常工作。 例如,对于这些输入,输出将是: 1公斤 输出:2.2046 3.1公斤 输出:6.8343 但是当输入为0时,输出应为0.0000,但
问题内容: 是一个字符串,而%d是一个小数,我想…但是放入时 ..引发异常,告诉我!= lang.double。有想法吗? 问题答案: 是供整数使用的,它同时适用于和类型: