1

I am trying to compute the value of F where F= 1/(1^(1/3)) + 1/(2^(1/3)) + ...... + 1/(600000000^(1/3)). I am using the following classes, however the output of each F1, F2, F3 and F4 returns 150000000. Upon closer inspection, I found that every time the value is added to sum, a 1 is added to the sum. How can i get accurate values for extremely small decimal places instead of turning it to a 1?

import java.util.Date;

public class Problem1 {

    public static void main(String[] args) throws InterruptedException{

        //start measuring time
        long begTime = new Date().getTime();

        //Measure execution time of following statements
        MyThread t1 = new MyThread();
        MyThread t2 = new MyThread();
        MyThread t3 = new MyThread();
        MyThread t4 = new MyThread();

        t1.n1 = 1;
        t1.n2 = 150000000;

        t2.n1 = 150000001;
        t2.n2 = 300000000;

        t3.n1 = 300000001;
        t3.n2 = 450000000;

        t4.n1 = 450000001;
        t4.n2 = 600000000;

        t1.start();
        t2.start();
        t3.start();
        t4.start();

        t1.join();
        t2.join();
        t3.join();
        t4.join();

        System.out.printf("Value of F1 is %f\n", t1.sum);
        System.out.printf("Value of F2 is %f\n", t2.sum);
        System.out.printf("Value of F3 is %f\n", t3.sum);
        System.out.printf("Value of F4 is %f\n", t4.sum);
        System.out.println();

        System.out.printf("Value of F is %f\n", t1.sum+t2.sum+t3.sum+t4.sum);



        //Compute and print elapsed time
        double timeElapsed = (new Date().getTime() - begTime) * 0.001;
        System.out.printf("Time elapsed = %f secs\n", timeElapsed);

    }
}

public class MyThread extends Thread {

    int n1, n2;
    double sum = 0.0;

    public void run(){

        for (int i=n1; i<= n2;i++){
            sum = sum+ (1/(Math.pow((double) i, (double) (1/3))));


        }

    }

}
Tan Yu Hau Sean
  • 585
  • 6
  • 16
  • 2
    You should just have a quick look what `System.out.println((double) (1/3));` actually outputs. `1` and `3` are both integers so `1/3` will always return the int `0`. Casting to double after you already did the integer division is to late in that case. – OH GOD SPIDERS Mar 18 '20 at 14:34
  • 1
    By the way, for elapsed time call [`System.nanoTime`](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/System.html#nanoTime()). Or use the [JEP 230 Microbenchmark Suite](https://openjdk.java.net/jeps/230). – Basil Bourque Mar 18 '20 at 14:48

3 Answers3

3

You can use BigDecimal instead of double. https://docs.oracle.com/javase/7/docs/api/java/math/BigDecimal.html

This might also help. Double vs. BigDecimal?

user12047085
  • 162
  • 1
  • 12
1

If the type of number not a problem, you should use BigDecimal's.

Its more powerful than Doubles, and can put more decimals, and other operations like rounds in native

https://docs.oracle.com/javase/7/docs/api/java/math/BigDecimal.html

And this thread explain much better.

Double vs. BigDecimal?

Adrian Lagartera
  • 442
  • 1
  • 3
  • 17
0

This is normal behaviour of float and double as seen here.

Consider using BigDecimal objects as they are way more powerful for exact arithmetic operations.

torblerone
  • 163
  • 1
  • 1
  • 10