是否有一种舍入算法可以撤消基数2转换并推断精度*希望是java*
如果我有一个像3.01这样的数字,计算机似乎认为最好的双精度是64位数字:是否有一种舍入算法可以撤消基数2转换并推断精度*希望是java*,java,rounding,Java,Rounding,如果我有一个像3.01这样的数字,计算机似乎认为最好的双精度是64位数字: 3.0099999999999997868371792719699442386627197265625 有没有比寻找四个以上的9或0更好的方法,我可以将其“四舍五入”到精确的10进制表示 有没有一个算法可以接受3.00999999。。。mess并返回3.01,无需我指定需要该精度 double d = 3.01; System.out.println(d); // rounds the answer slightly
3.0099999999999997868371792719699442386627197265625
有没有比寻找四个以上的9或0更好的方法,我可以将其“四舍五入”到精确的10进制表示
有没有一个算法可以接受3.00999999。。。mess并返回3.01,无需我指定需要该精度
double d = 3.01;
System.out.println(d); // rounds the answer slightly
我认为我处理的大多数数字都应该足够小,64位不会有歧义。否-因为您可能实际上指定了3.009999999997868作为输入数字,并且不希望将相同的值四舍五入到3.01。基本上,当从十进制值转换为二进制浮点值时,您已经丢失了信息—您无法恢复这些信息
如果你对十进制值感兴趣,而不仅仅是大小,你应该考虑使用<代码> BigDecimal <代码>而不是<代码>双。(这些值代表什么?)
编辑:正如其他答案所指出的,当您仅使用toString
时,Java将为您提供3.01版本,但是您得到了原始值。这在Double.toString
中指定:
m或a的小数部分必须打印多少位?必须至少有一个数字来表示小数部分,除此之外,还必须有尽可能多的数字,但只能有尽可能多的数字来唯一区分参数值与double类型的相邻值。也就是说,假设x是精确的数学值,由该方法为有限非零参数d生成的十进制表示表示。那么d必须是最接近x的两倍值;或者,如果两个双精度值与x相等,则d必须是其中之一,并且d的有效位的最低有效位必须为0
如果这对你来说足够好的话,它会让你的生活更轻松。。。但是听起来你应该从根本上考虑这个问题。否-因为你可能实际上指定了3.009999999997868作为输入数字,并且不希望将相同的值四舍五入到3.01。基本上,当从十进制值转换为二进制浮点值时,您已经丢失了信息—您无法恢复这些信息
如果你对十进制值感兴趣,而不仅仅是大小,你应该考虑使用<代码> BigDecimal <代码>而不是<代码>双。(这些值代表什么?)
编辑:正如其他答案所指出的,当您仅使用toString
时,Java将为您提供3.01版本,但是您得到了原始值。这在Double.toString
中指定:
m或a的小数部分必须打印多少位?必须至少有一个数字来表示小数部分,除此之外,还必须有尽可能多的数字,但只能有尽可能多的数字来唯一区分参数值与double类型的相邻值。也就是说,假设x是精确的数学值,由该方法为有限非零参数d生成的十进制表示表示。那么d必须是最接近x的两倍值;或者,如果两个双精度值与x相等,则d必须是其中之一,并且d的有效位的最低有效位必须为0
如果这对你来说足够好的话,它会让你的生活更轻松。。。但是听起来你应该从根本上考虑这个问题。如果你想要10位数的精度,你需要四舍五入到这个精度。即使使用BigDecimal,也可以避免表示错误,但迟早要知道如何处理精度
double d = 3.01;
System.out.println(d); // rounds the answer slightly
印刷品
3.01
表示和舍入误差有很多解决方法,但通常内置工具会为您解决。如果您需要10位精度,则需要舍入到该精度。即使使用BigDecimal,也可以避免表示错误,但迟早要知道如何处理精度
double d = 3.01;
System.out.println(d); // rounds the answer slightly
印刷品
3.01
表示法和舍入误差有很多解决方法,但通常内置的工具会为您处理。很明显,您不能期望总是返回原始数字,因为有许多数字映射到同一个浮点数。例如,您无法区分以下数字:
3.0099999999999997868371792719699442386627197265625
3.009999999999999786837179271969944238662
3.009999999999999786837179271
3.0099999999999997
3.01
然而,Python对此有一个有趣的理解:如果您给它3.0099999999997868371792719699442386627197265625,它将用3.01回复:
Python 2.7.2+ (default, Nov 30 2011, 19:22:03)
[GCC 4.6.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> 3.0099999999999997868371792719699442386627197265625
3.01
这是因为3.01
是给出相同浮点数的最短字符串。换句话说,它是最短的x
,因此
float(repr(x)) == x
其中,repr
是将对象转换为字符串的Python函数(这里它将3.0099…
转换为3.01
),并且float
将字符串转换为float
显然有许多字符串会导致相同的内部浮动,但这是最短的,因此“可能”是您的意思
这个特性作为Python3.1特性的一个后端口被使用。是的,您应该能够在那里找到代码,并根据需要将其转换为Java。很明显,您不能期望总是返回原始数字,因为有许多数字映射到同一个浮点数。例如,您无法区分以下数字:
3.0099999999999997868371792719699442386627197265625
3.009999999999999786837179271969944238662
3.009999999999999786837179271
3.0099999999999997
3.01
然而,Python对此有一个有趣的理解:如果您给它3.0099999999997868371792719699442386627197265625,它将用3.01回复:
Python 2.7.2+ (default, Nov 30 2011, 19:22:03)
[GCC 4.6.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> 3.0099999999999997868371792719699442386627197265625
3.01
这是因为3.01
是给出相同浮点数的最短字符串。换句话说,它是最短的x
,因此
float(repr(x)) == x
其中,repr
是将对象转换为字符串的Python函数(这里它将3.0099…
转换为3.01
),并且float
将字符串转换为floa