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