We closed this forum 18 June 2010. It has served us well since 2005 as the ALPHA forum did before it from 2002 to 2005. New discussions are ongoing at the new URL http://forum.processing.org. You'll need to sign up and get a new user account. We're sorry about that inconvenience, but we think it's better in the long run. The content on this forum will remain online.
IndexProgramming Questions & HelpSyntax Questions › (double) initialization
Page Index Toggle Pages: 1
(double) initialization (Read 321 times)
(double) initialization
Mar 5th, 2009, 5:21pm
 
Hi All,

I looked into using double precision instead of floats for doing simple numerics but couldnt find any precision improvement in my results.

Further debugging this I found some difference in how the same code runs in the processing environment compared to running as standard java code. The example code repeatedly ("cnt" times) adds a float or double value "dy" and at the end compares the result to the multiple "cnt*dy". See the listing below.

Now when executing these lines

Quote:
  testRoundingError test = new testRoundingError();
  test.singleAddition(2000);
  test.doubleAddition(2000);


the printed output is

Quote:
Processing:
single: n=2000, dy=0.1,                 n*dy=200.0,              y=200.003,            err=1.5029907E-5
double: n=2000, dy=0.10000000149011612, n*dy=200.00000298023224, y=200.00000298023224, err=0.0

Java:
single: n=2000, dy=0.1, n*dy=200.0, y=200.003,            err=1.5029907E-5
double: n=2000, dy=0.1, n*dy=200.0, y=199.99999999999292, err=-3.538502824085299E-14

Matlab
single: n=2000, dy=0.1000000014901161, n*dy=200.0000000000000000, y=200.0030059814453100, err=1.503E-005
double: n=2000, dy=0.1000000000000000, n*dy=200.0000000000000000, y=199.9999999999929200, err=-3.539E-014


The results in Java are what is expected, while the Processing results look like already setting
 double dy=(double)0.1;
 -> dy=0.10000000149011612
does not initialize all digits of the double value. The result for "err" in double precision is certainly not correct.

Sidenote: Originally I wanted to try out the integration of a simple differential equation in Processing and realized that even with double precision the results were unstable and different to an implementation in Matlab. Then I traced the issue down to this potential bug in initializing doubles.

Paul

Quote:
/**
 * Test rounding error.
 * 
 * @author P.B. 
 * @version 20090305
 */
public class testRoundingError
{
    /**
     * Constructor for objects of class testRoundingError
     */
    public testRoundingError(){}

    /**
     * test using addition in double precision
     * 
     * @param int cnt  number of additions
     */
    public void doubleAddition(int cnt)
    {
        // test rounding errors
        double y0, y, dy, err;
        int n;
        
        y=(double)0.0000000000000000;
        dy=(double)0.1000000000000000;
        for(n=1;n<=cnt;n++){
          y=y+dy;
        }
        y0=(double)cnt * dy;
        err=(y-y0)/y0;
        System.out.println("double: n="+cnt+", dy="+dy+", n*dy="+y0+", y="+y+", err="+err);
    }

    /**
     * test using addition in single precision
     * 
     * @param int cnt  number of additions
     */
    public void singleAddition(int cnt)
    {
        // test rounding errors
        float y0, y, dy, err;
        int n;
        
        y=(float)0.0;
        dy=(float)0.10000000;
        for(n=1;n<=cnt;n++){
          y=y+dy;
        }
        y0=(float)cnt * dy;
        err=(y-y0)/y0;
        System.out.println("single: n="+cnt+", dy="+dy+", n*dy="+y0+", y="+y+", err="+err);
    }

}

Re: (double) initialization
Reply #1 - Mar 5th, 2009, 7:11pm
 
found a workaround for initializing a double to "0.1":
       dy=(double)1/(double)10;
 print shows dy=0.1
 -> the cast of integer to double works fine.

Not working:

initializing a double variable

       double dy=0.1;
 print shows dy=0.10000000149011612

is the same as a cast from (float) to (double)

       float tmpf=0.1;
       double tmpd=(double)tmpf;
 print shows tmpf=0.1
 print shows tmpd=0.10000000149011612

Paul
Re: (double) initialization
Reply #2 - Mar 5th, 2009, 9:37pm
 
See How to add a double literal for why it doesn't work in Processing and how to workaround this properly.
Re: (double) initialization
Reply #3 - Mar 6th, 2009, 1:54pm
 
thanks for your answer.

The workaround using Double.parseDouble(String) for a double literal is certainly better compared to the workaround above.

Why there has to be a workaround like this in Processing I didnt really understand. Probably I dont know enough about the preprocessor.

I would have two suggestions:

Mention in the tutorial that literals are by default floats and not doubles. I couldnt find this hint.

Allow defining literals with the "d" like
 double y=0.1d;
Re: (double) initialization
Reply #4 - Mar 6th, 2009, 2:32pm
 
Actually, the best workaround is probably, as indicated in the cited thread, to put initializations of doubles (and perhaps computations) in a separate .java file, to avoid P5's pre-processing of source (adding F after non-integer numerical constants and such...).
Page Index Toggle Pages: 1