在下面给出测试代码及其输出。当我从数值获得浮点值时,精度会丢失..任何人都可以告诉我为什么这种行为以及如何处理这个问题?
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_VALUE?
答案 0 :(得分:21)
float
通常最多可达6位有效数字。您的电话号码是676543.21
,其中有8位有效数字。您将看到超过6位数的错误,并且这些错误很容易传播到您执行的计算越多的有效数字。如果您重视您的理智(或精确度),请使用double
s。浮标甚至不能准确计算超过1000万。
现在,您有2位有效数字,这表明您有可能想要代表货币 - 不要。使用您自己的类,使用定点算法在内部表示值。
现在,至于Float.MAX_VAL
是3.4028235E38,意思是3.4028235 * 10 ^ 38,这比你的值大10 ^ 32倍。注意那里的'E'?那是指数。
答案 1 :(得分:8)
我喜欢这些。但我会快速而轻松地做到这一点。
浮点数和小数(也就是浮点数)也没有精确地保存在内存中。但我不想在这里考虑浮动精度与精度问题,我只想指出一个链接 - http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm
至于你的另一个问题,lemme就是这样说的,因为花车以科学记数法存储。
floatVal = 6.765432E6 = 6.7 * 10^6
MAX_VALUE = 3.4E38 = 3.4 * 10^38
MAX_VALUE比您的浮点数大32个数量级。请随意查看此处http://steve.hollasch.net/cgindex/coding/ieeefloat.html
几个月前我花了很多时间来比较和解决一些FP问题......
比较浮点数时尝试使用小的delta。 也许这个链接可以帮助您http://introcs.cs.princeton.edu/java/91float/
答案 2 :(得分:7)
所有数据类型都有表示限制,因此存在限制的事实不应该令人惊讶。
float
使用24位作为其“尾数”,其中包含所有有效数字。这意味着它具有大约7位数的精度(因为2 ^^ 24大约是1600万)
double
使用53位的“尾数”,因此它可以准确地保存大约16位。
答案 3 :(得分:2)
3.4028235E38大于676543.2。 Float.MAX_VALUE是可以表示的最大浮点数。
答案 4 :(得分:0)
您键入的十进制文字默认为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
查看类型精度的差异
Float.MAX_VALUE
返回浮点数可以容纳的最大值。任何更高的将溢出。如果仔细观察,你会在文字表示中看到“E”。这是标准索引形式,'E'表示“乘以10乘以E后的任何数字的幂”(或在java-speak * pow(10,numberAfterE))