0

I am trying to compute a summation of float numbers. All small numbers output properly, when I use very large numbers as inputs, the output is always off by a few integers. For example, H = 5764801 W = 1679616, on paper, works out as 335923 30275911. In my program though, 335923 30275908 is printed instead. Here is the code:

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;
}

}

1
  • any reason not to use double?
    – Ousmane D.
    Commented Apr 30, 2017 at 18:18

2 Answers 2

2

Floating point numbers have a limited precision as mantissa has a limited width.

You could try double for your case which precision is more (as its mantissa is wider), but it is also limited.

More information: https://en.wikipedia.org/wiki/IEEE_floating_point#IEEE_754-2008 and What is the maximum number in the mantissa part of a Java float?

If you need to have an unlimited precision, try BigDecimal. The count of significant digits there is only limited by the amount of your memory.

If you only need integer values, BigInteger is an option.

1

Study What Every Computer Scientist Should Know About Floating-Point Arithmetic, David Goldberg, 1991. https://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html

Not the answer you're looking for? Browse other questions tagged or ask your own question.