【问题标题】:Loss of accuracy with floats浮点数的准确性损失
【发布时间】:2017-04-30 18:17:10
【问题描述】:

我正在尝试计算浮点数的总和。所有小数字都正确输出,当我使用非常大的数字作为输入时,输出总是偏离几个整数。例如,H = 5764801 W = 1679616,在纸面上计算为 335923 30275911。不过,在我的程序中,打印的是 335923 30275908。代码如下:

public void printOutput(int H, int W) // The inputs
{
    if(H == 1 && W == 1)
    {
        System.out.println(0 + " " + 1);
        return;
    }

    List<Integer> pfw = primeFactors(W);

    int y = 1;

    while(H != (int) (Math.pow(Math.pow(W,  1f/y) + 1f, y))) y++; 

    final float N = findWholeNumber(pfw);

    float height = 0;
    for(int x = 1; x <= y + 1; x++)
    {
        height += (float) (W * Math.pow((N + 1f) / N, x-1f) + 1e-8); //Here is the summation
    }
    float cats = 1;
    for(int x = 2; x <= y + 1; x++)
        cats += (float) (Math.pow(N, x-1));

    int notWorking = (int) (cats - W);
    System.out.println(notWorking + " " + (int)height); //Outputs printing
}

private int findWholeNumber(List<Integer> factors)
{
    List<Integer> common = new ArrayList<Integer>();
    for(int i = 0; i < factors.size(); i++)
    {
        if(common.contains(factors.get(i))) continue;
        common.add(factors.get(i));
    }
    int num = common.get(0);
    for(int i = 1; i < common.size(); i++)
        num *= common.get(i);
    return num;
}

private List<Integer> primeFactors(int num)
{
    List<Integer> pf = new ArrayList<Integer>();

    if(num == 1)
    {
        pf.add(1);
        return pf;
    }

    for(int j = 2; j <= num; j++)
        while(num % j == 0) // is prime
        {
            pf.add(j);
            num /= j;
        }

    return pf;
}

}

【问题讨论】:

  • 有什么理由不使用double

标签: java floating-point floating-accuracy


【解决方案1】:

浮点数的精度有限,因为尾数的宽度有限。

对于您的情况,您可以尝试double,哪个精度更高(因为它的尾数更宽),但它也是有限的。

更多信息:https://en.wikipedia.org/wiki/IEEE_floating_point#IEEE_754-2008What is the maximum number in the mantissa part of a Java float?

如果您需要无限精度,请尝试BigDecimal。有效数字的数量仅受您的内存量的限制。

如果您只需要整数值,BigInteger 是一个选项。

【讨论】:

    【解决方案2】:

    研究每个计算机科学家都应该知道的关于浮点运算的知识,David Goldberg,1991 年。 https://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html

    【讨论】:

      猜你喜欢
      • 2020-08-08
      • 1970-01-01
      • 1970-01-01
      • 2010-09-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多