使用java时浮点值丢失的精度
下面给出了测试代码及其输出。当我从数值中获取浮点值时,精度将丢失。。有谁能告诉我为什么会有这种行为,以及如何处理使用java时浮点值丢失的精度,java,floating-point,Java,Floating Point,下面给出了测试代码及其输出。当我从数值中获取浮点值时,精度将丢失。。有谁能告诉我为什么会有这种行为,以及如何处理 public static void main(String[] args) { try { java.lang.Number numberVal = 676543.21; float floatVal = numberVal.floatValue(); System.ou
public static void main(String[] args)
{
try
{
java.lang.Number numberVal = 676543.21;
float floatVal = numberVal.floatValue();
System.out.println("Number value : " + numberVal);
System.out.println("float value : " + floatVal);
System.out.println("Float.MAX_VALUE : " + Float.MAX_VALUE);
System.out.println("Is floatVal > Float.MAX_VALUE ? " + ( floatVal > Float.MAX_VALUE));
}catch(Exception e)
{
e.printStackTrace();
}
}
输出:
Number value : 676543.21
float value : 676543.2
Float.MAX_VALUE : 3.4028235E38
Is floatVal > Float.MAX_VALUE ? false
为什么浮点值小于float.MAX_值 3.4028235E38大于676543.2。Float.MAX_值是可能表示的最大浮点。十进制文本,如您键入的文本,默认为键入
double
,而不是Float
。默认情况下,java.lang.Number也使用双精度。如果要用java.lang.Number numberVal=676543.21f替换它代码>我预计两者的精度损失程度相同。或者,替换float floatVal=numberVal.floatValue()代码>带有double doubleVal=numberVal.doubleValue()代码>以避免丢失精度
例如,请尝试运行以下命令:
Number num = 676543.21;
System.out.println(num); //676543.21
System.out.println(num.doubleValue()); //676543.21
System.out.println(num.floatValue()); //676543.2 <= loses the precision
Number num=676543.21;
系统输出打印项数(num)//676543.21
System.out.println(num.doubleValue())//676543.21
System.out.println(num.floatValue())//676543.2我喜欢这些。但我会让它快速无痛
浮点和小数(也称为浮点)也不会精确地保存在内存中。但我不想在这里讨论浮点精度与精度的问题,我只给你们指出一个链接-
至于你的另一个问题,让我这么说,因为浮点数是用科学记数法存储的
floatVal = 6.765432E6 = 6.7 * 10^6
MAX_VALUE = 3.4E38 = 3.4 * 10^38
最大值比浮点数大32个数量级。请随意看看这里
几个月前,我花了大量时间比较和修复一些FP问题
在比较浮动时,尝试使用小的增量。
也许这个链接可以帮助您所有数据类型都有表示限制,因此存在限制的事实并不令人惊讶
float
使用24位作为其“尾数”,该尾数包含所有有效数字。这意味着它有大约7位精度(因为2^^24约为1600万)
double
使用53位作为“尾数”,因此它可以准确地容纳大约16位。float
s通常最多可容纳6位有效数字。您的号码是676543.21
,有8位有效数字。您将看到超过6位的错误,并且执行的计算越多,这些错误将很容易传播到更重要的数字。如果您重视您的理智(或精确性),请使用double
s。浮动甚至不能准确计算超过1000万
现在,您有两个有效数字,这对我来说意味着您有可能想要表示货币-不要。使用您自己的类,该类使用定点算术在内部表示值
现在,关于Float.MAX_VAL,它是3.4028235E38,意思是3.4028235*10^38,比你的值大10^32倍。注意到里面的“E”了吗?这是指数。676543.2<3.4028235E38=340282350000000000000000000000000000000000000000000000000000是的,注意输出中的E
!不是真的,676543.21
也不能表示为双精度。@assylias是真的。试试数字num=676543.21;系统输出打印项数(num);System.out.println(num.doubleValue());System.out.println(num.floatValue());您将看到正在被评论的精度损失。这是646543.21d
的实际值:646543.20999999962747097015380859375
println
在打印之前对数字进行四舍五入-因此这不是一种可靠的检查方法。尝试System.out.println(新的BigDecimal(646543.21d))代码>以查看实际值。是的,但我是说使用double“为了不失去精度”是不正确的-它将提高精度,但仍然是不精确的。还要注意,浮点打印为676543.2,但其实际值为646543.1875。这是我发现的最简单、最直接的解释。谢谢