我正在阅读关于Java的Mikael Eliasson并遇到了一些我不太了解的事情。在覆盖变量类型时,作者声明“单词double
代表之间的数字
这让我感到很奇怪,因为如上所述,它将包括上述两个限制之间的实数行上的所有数字。
根据我的理解,double
是一个分配64位内存的原始数据类型。反过来,我很清楚5.9是完美的双倍,或浮动。但是,我不确定该系列如何
即5.9,5.99,5.999,5.9999,......当 k 接近无穷大时,将适合记忆。
我的直觉是否正确不是所有作者的两个限制之间的实数在内存中被恰当地保存为double
?
答案 0 :(得分:3)
事实上。在一个句子中,整数是精确的,而浮点数和双精度数则使用以位为单位的科学记数法存储。这意味着将出现一个舍入错误,就像科学记法一样。
根据维基百科:
符号位:1位
指数宽度:11位
显着精度:53位(显式存储52位)
一个有趣的说明:指数也有1位存储其符号!
答案 1 :(得分:3)
我的直觉是,并非作者的两个限制之间的所有实数都会在记忆中被恰当地保存为双重?
是的,你是对的。
即便是最明显的"双打"无法正确存储。例如0.1
是" 1/10" - 你有没有在基础2系统中除以10?这是一个无限的数字(与基础10系统中的" / 3"相当)
(这个事实btw负责Patriot-Bug:http://sydney.edu.au/engineering/it/~alum/patriot_bug.html)
因此,即使是一些明显的简单数学也会在java上出错:
选择您喜欢的编译器并尝试:
System.out.println(0.8 == (0.1 + 0.7));
糟糕,它会输出错误。
答案 2 :(得分:3)
双数据类型是双精度64位(8字节)IEEE-754浮点。格式包括1位用于符号,11位用于指数,其余52位有效数字表示分数部分。由于分数有效数的52位出现在存储器格式中,因此总精度为53位(大约16位十进制数,53 log10(2)≈15.955)。指数的11位宽度允许表示数字,其小数指数在10E-308和10E + 308之间,精度为15-17十进制数。 Double和float并不是真正的数字。在任何范围内都可以有无限数量的实数,但应始终记住,只有有限数量的位来表示它们,因此不能表示所有数字。< / p>
为了获得更高和更好的精度,您可以使用java.math包中的BigDecimal类。 http://docs.oracle.com/javase/7/docs/api/java/math/BigDecimal.html