Bug #6439
closed
Double rounding fails in some cases while evaluating Expressions
Added by Owsiak Michal over 10 years ago.
Updated over 10 years ago.
Description
It seems that addition of doubles can produce values slightly different than they should to be.
Please take a look at attached workflow (simple_error.xml).
Condition that should be satisfied to escape the loop is: 1.7 > 1.5 + 0.1
However, loop is interrupted sooner, because of incorrect calculation of doubles. Value of "p" is set to: 1.6000000000000003
This, of course, makes it impossible to use doubles as check points for the loops.
However, it seems that casting to string and back works fine (take a look at second workflow - simple.xml)
Cheers
Michal
Files
- Status changed from New to Closed
- Assignee changed from Derik Barseghian to Christopher Brooks
- % Done changed from 0 to 100
It is almost never a good idea to compare doubles without using an epsilon factor. Because of rounding, doubles are unlikely to precisely represent a value.
One workaround in the expression language is to use
close(value1, value2)
which is defined as:
Return true if the first argument
is close to the second (within
EPSILON, where EPSILON is
a static public variable of this
class)
Tokens also have an isCloseTo() method:
/** Test whether the value of this Token is close to the argument
* Token. The argument and this token are converted to
* equivalent types, and then compared. Generally, this is the
* higher of the type of this token and the argument type.
* Subclasses should implement the protected _isCloseTo() method
* to perform the correct type-specific operation.
* @see #isEqualTo
* @param rightArgument The token to test closeness of this token with.
* @param epsilon The value that we use to determine whether two
* tokens are close.
* @return A boolean token that contains the value true if the
* units of this token and the argument token are the same, and their
* values are close.
* @exception IllegalActionException If the argument token is not
* of a type that can be compared with this token, or the units
* are not the same.
*/
public final BooleanToken isCloseTo(Token rightArgument, double epsilon)
See 13.4.1 Invoking Methods in http://ptolemy.eecs.berkeley.edu/books/Systems/chapters/Expressions.pdf
Also available in: Atom
PDF