5

下面给出了测试代码及其输出。当我从数值中获取浮点值时,精度会丢失。谁能告诉我为什么会出现这种行为以及如何处理?

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?

4

5 回答 5

24

floats 通常最多 6 位有效数字。您的号码676543.21有 8 位有效数字。您看到超过 6 位的错误,并且执行的计算越多,这些错误很容易传播到更多有效数字。如果您重视您的理智(或精确度),请使用doubles。浮点数甚至无法准确计算超过 1000 万。

现在,您有 2 位有效数字,这向我表明您有可能想要代表货币 - DO NOT。使用您自己的类,该类使用定点算术在内部表示值。

现在,Float.MAX_VAL哪个是 3.4028235E38,意思是 3.4028235*10^38,大约是你的值的 10^32 倍。注意到里面的“E”了吗?那是指数。

于 2012-08-06T09:47:59.190 回答
9

所有数据类型都有表示限制,因此存在限制这一事实不足为奇。

float使用 24 位作为其“尾数”,它包含所有有效数字。这意味着它有大约 7 位的精度(因为 2^^24 大约是 1600 万)

double使用 53 位作为“尾数”,因此它可以准确地保存大约 16 位数字。

于 2012-08-06T09:44:44.950 回答
9

我爱这些。但我会让它快速而无痛。

浮点数和小数(又名浮点数)也不会精确地保存在内存中。但我不想在这里讨论浮点精度和精度问题,我只是给你一个链接 - http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm

至于你的另一个问题,让我这样说,因为浮点数是以科学记数法存储的。

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 问题......

比较浮点数时尝试使用小增量。也许这个链接会帮助你http://introcs.cs.princeton.edu/java/91float/

于 2012-08-06T09:43:50.383 回答
2

3.4028235E38 is greater than 676543.2. Float.MAX_VALUE is the largest float that is possible to represent.

于 2012-08-06T09:39:26.187 回答
1

十进制文字,例如您键入的默认文字double,而不是type 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) 中)

于 2012-08-06T09:42:06.330 回答