请问“的System.out.println(十进制)”总是输出相同的十进制代码?(Does “Sy

2019-10-19 11:21发布

当然, System.out.println( 0.1 ); 输出0.1 。 但是,它永远对一个任意的十进制? (排除的双号本身的精度而导致的情况下如,。 System.out.println( 0.10000000000000000001);输出0.1

当我打System.out.println( DECIMAL ); 我认为,DECIMAL被转换成二进制(双)和二进制转换成十进制(以十进制输出作为字符串)


想想下面的转换。

小数[D1] - >(CONVERSION1) - >二进制[B] - >(CONVERSION2) - >十进制[D2]

CONVERSION1:

的最近的二进制(的双显著位数的范围内)[D1]被选择为[B]

例如,[D1] 0.1 - > [B] 0x0.1999999999999a

CONVERSION2:

[D2]是可以唯一区分[B],并且具有最小的位的十进制数。

例如[B] 0x0.1999999999999a - > [D2] 0.1

QUOTE Java7 API Double.toString(双d)

必须多少位为m或a的小数部分? 必须有至少一个数来表示小数部分,并且除此之外,需要来唯一地区分型双的相邻值的参数值,作为许多,但仅作为许多,多个数字。 也就是说,假设x是由通过该方法对于有限的非零参数d产生的十进制表示法表示的精确的数学值。 然后d必须是最接近x的双值; 或者如果两个双值同样接近x,那么d必须它们中的一个和d的有效数字的最低位显著必须是0。


我的问题

是 “[D1] = [D2]” 总是为真?


我为什么问这个问题

有关下列情况下思考,

用户的十进制输入保存为双- >显示小数

我想知道[用户的输入显示=]是否保证与否。

(如上所述,排除的双号本身的精度而产生的情况下,由于其长的输入是罕见的情况。)

我知道当我需要精确的算法,我应该使用的BigDecimal。 但是,在这种情况下,我并不需要精确的算法。 只是想显示相同的数字作为用户的输入。

Answer 1:

这取决于在你的平等定义部分。 如果你需要精确的字符串匹配,答案是否定的。 例如:

System.out.println(0.1e-1);

版画

0.01

现在假设“相等”表示十进制的值相等,从而使0.1e-10.01是相等的。

如果你限制你的双打正常的数字(不低于正常,溢出或下溢)少于16个显著十进制数字,你是安全的。 小数的无限远四舍五入到,可以在双精确表示每个二进制小数。 要恢复原来的,它必须是该组的成员最短。 这意味着与相同或长度较短的两个最接近的十进制数它的区别必须足够大,以确保它们四舍五入到不同的双打。 要获得相同或长度较短的另一个十进制数至少需要一个小数的ULP原有数量的变化。

如果两个十进制数由一个以上的部分在2 ^ 54不同,并且在正常数范围内,它们相距甚远太映射到相同的两倍。

这个道理并不适用,因为它们比正常数字精密少次正规数:

System.out.println(0.123451234512345e-310);

版画

1.2345123451236E-311

即使输入只有15显著数字。



Answer 2:

第一转换,从十进制为二进制,可产生另一种数学值,因为不是每个小数可以精确地作为二进制数来表示。 这是二值的准确度的真正独立的,取0.1,例如,

第二转换,从二进制到十进制,总是有可能在一个无损耗的方式,即产生相同的数学值。 这将在一般需要一个很长的离谱十进制表示因此在实践中,你将价值圆在更短的代表性,这是则不再相同的数学值。

在回答你的问题“是[D1] = [D2]始终是真的吗?” 因此在一般无。 这一切都取决于二进制和十进制表示的准确性。



文章来源: Does “System.out.println( DECIMAL )” always output the same DECIMAL in the code?