rounding off double values

J

jimgardener

hi
i am comparing elements of two double[] .one is an expected set like
double[] expected=new double[]{ 1.246,2.343,4.568};

while the second array is result of some calculation
public double[] mycalculations(){
double[] res=null;
......//calculate the array
....
return res;
}
and can be
{ 1.246,2.3430000001,4.56800002 }

for practical purposes these two are equal,when you round off the
elements to 3 decimal places.if i want to unit test my code i need to
compare elements of both arrays .How do i do the rounding off?
DecimalFormat only helps me to print or display the numbers.I need
some way to compare like

for(int i=0;i<expected.length;i++){
assertEquals( roundoff( expected ),roundoff( result[ i] ) );
}

can anybody suggest a way to do this?

thanks
jim
 
A

Andreas Leitgeb

jimgardener said:
i am comparing elements of two double[] .one is an expected set like
double[] expected=new double[]{ 1.246,2.343,4.568};
while the second array is result of some calculation
and can be
{ 1.246,2.3430000001,4.56800002 }

It may surprise you, that even the first set is not *exactly* what it
seems to be. Try:
for (double d: expected) { System.out.println(d); }
for(int i=0;i<expected.length;i++){

assertEquals( (int)((expected*2000+1)/2),
(int)((result*2000+1)/2) );
Will check three decimal places for equality.
 
J

John B. Matthews

jimgardener said:
hi
i am comparing elements of two double[] .one is an expected set like
double[] expected=new double[]{ 1.246,2.343,4.568};

while the second array is result of some calculation
public double[] mycalculations(){
double[] res=null;
.....//calculate the array
...
return res;
}
and can be
{ 1.246,2.3430000001,4.56800002 }

for practical purposes these two are equal,when you round off the
elements to 3 decimal places.if i want to unit test my code i need to
compare elements of both arrays .How do i do the rounding off?
DecimalFormat only helps me to print or display the numbers.I need
some way to compare like

for(int i=0;i<expected.length;i++){
assertEquals( roundoff( expected ),roundoff( result[ i] ) );
}


Something like this:

private boolean nearEnough(double v1 , double v2) {
return (Math.abs(v1 - v2) < 0.001);
}

["Now near enough..." --Macbeth, act V, scene 6]
 
J

Jussi Piitulainen

jimgardener said:
i am comparing elements of two double[] .one is an expected set like
double[] expected=new double[]{ 1.246,2.343,4.568};

while the second array is result of some calculation
public double[] mycalculations(){
double[] res=null;
.....//calculate the array
...
return res;
}
and can be
{ 1.246,2.3430000001,4.56800002 }

for practical purposes these two are equal,when you round off the
elements to 3 decimal places.if i want to unit test my code i need to
compare elements of both arrays .How do i do the rounding off?
DecimalFormat only helps me to print or display the numbers.I need
some way to compare like

for(int i=0;i<expected.length;i++){
assertEquals( roundoff( expected ),roundoff( result[ i] ) );
}

can anybody suggest a way to do this?


If you know that all your numbers are of that magnitude, you may get
by with asserting that the absolute difference of the expected and
observed value is smaller than a threshold, like so:

assert(Math.abs(result - expected) < 0.00000001)

This fails with numbers very far from 0, where a negligible difference
can be much larger, and numbers very close to 0 where that threshold
is already huge compared to the numbers themselves. Think of 1e14 and
1e-14. That's where floating points becomes scary, but maybe you don't
need to go there. Two terms to search for are "absolute error" and
"relative error".

(There is a concept of ulps, though: units in the last position. It is
possible to find out how many floating point numbers there are between
the expected and observed value. They are numerically much denser near
zero than far from zero, but this seems to measure whether the program
worked as well as it can given that you use floating point.)
 
J

Jean-Baptiste Nizet

hi
i am comparing elements of two double[] .one is an expected set like
double[] expected=new double[]{ 1.246,2.343,4.568};
<snip>
can anybody suggest a way to do this?

for (int i = 0; i < expected.length; i++) {
assertEquals(expected, result, 0.001);
}

0.001 being the delta you tolerate between your expected and actual
values (see the javadoc for JUnit)

JB.
 
D

Daniel Pitts

jimgardener said:
hi
i am comparing elements of two double[] .one is an expected set like
double[] expected=new double[]{ 1.246,2.343,4.568};

while the second array is result of some calculation
public double[] mycalculations(){
double[] res=null;
......//calculate the array
....
return res;
}
and can be
{ 1.246,2.3430000001,4.56800002 }

for practical purposes these two are equal,when you round off the
elements to 3 decimal places.if i want to unit test my code i need to
compare elements of both arrays .How do i do the rounding off?
DecimalFormat only helps me to print or display the numbers.I need
some way to compare like

for(int i=0;i<expected.length;i++){
assertEquals( roundoff( expected ),roundoff( result[ i] ) );
}

can anybody suggest a way to do this?

thanks
jim

If you are using JUnit, then there is an assertEquals method that takes
three doubles, the first is the expected, the second is the actual, and
the third is the allowed delta.

for (int i = 0; i < expected.length; ++i) {
assertEquals(expected, result, 0.0001);
}

Hope this helps,
Daniel.

P.S.
double[] res=null; // Ready for a NPE later on!

don't initialize to null if you know you won't return null.

use
final double[] res;
if (!canCalcRes()) {return null;}
res = new double[......
 
A

Arne Vajhøj

Jean-Baptiste Nizet said:
hi
i am comparing elements of two double[] .one is an expected set like
double[] expected=new double[]{ 1.246,2.343,4.568};
<snip>
can anybody suggest a way to do this?

for (int i = 0; i < expected.length; i++) {
assertEquals(expected, result, 0.001);
}

0.001 being the delta you tolerate between your expected and actual
values (see the javadoc for JUnit)


Not only does it work, but it makes sense from a testing
perspective.

For floating point accuracy is part of the contract that
the unit tests are checking for compliance.

Arne
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,535
Members
45,007
Latest member
obedient dusk

Latest Threads

Top