edu.mines.jtk.util
Class Almost

java.lang.Object
  extended by edu.mines.jtk.util.Almost
All Implemented Interfaces:
java.io.Serializable, java.util.Comparator<java.lang.Number>

public class Almost
extends java.lang.Object
implements java.io.Serializable, java.util.Comparator<java.lang.Number>

This class allows safe comparisons of floating point numbers with limited precision. The Comparator interface should be used for instances of java.lang.Number.

Author:
W.S. Harlan
See Also:
Serialized Form

Field Summary
static Almost DOUBLE
          This instance uses default double precision
static Almost FLOAT
          This instance uses default float precision
 
Constructor Summary
Almost()
          Accept default precision, appropriate for arithmetic on floats.
Almost(boolean isDouble)
          Constructor that allows either double or float precision.
Almost(double epsilon)
          Specify precision to be used for operations.
Almost(double epsilon, double minValue)
          Specify precision to be used for operations.
Almost(int significantDigits)
          Specify precision to be used for operations.
 
Method Summary
 boolean between(double x, double x1, double x2)
          See if value is between two other values, including almost equality
 int cmp(double r1, double r2)
          Check order of two numbers, within precision.
 int compare(java.lang.Number n1, java.lang.Number n2)
           
 double divide(double top, double bottom, boolean limitIsOne)
          Safely divide one number by another.
 double divide(double top, double bottom, double limit)
          Safely divide one number by another.
 boolean equal(double r1, double r2)
          See if two numbers are almost equal.
 boolean equals(java.lang.Object object)
           
 boolean ge(double r1, double r2)
          Check whether first number is greater than or equal to second.
 double getEpsilon()
          Get the smallest positive number that can be added to 1 before the number is considered different from 1.
 double getMinValue()
          Get the smallest positive value that should be distinguished from zero.
 boolean gt(double r1, double r2)
          Check whether first number is strictly greater than second.
 int hashCode()
           
 int hashCodeOf(java.lang.Number number)
          Return a hashcode consistent with imprecise floating-point equality.
 int hashCodeOf(java.lang.Number number, int significantDigits)
          Return a hashcode consistent with imprecise floating-point equality.
 boolean le(double r1, double r2)
          Check whether first number is less than or equal to second.
 boolean lt(double r1, double r2)
          Check whether first number is strictly less than second.
 int outside(double x, double x1, double x2)
          See if value is outside two other values.
 double reciprocal(double value)
          Safely take the reciprocal of a number.
 java.lang.String toString()
           
 boolean zero(double r)
          See if the number is almost zero
 
Methods inherited from class java.lang.Object
clone, finalize, getClass, notify, notifyAll, wait, wait, wait
 

Field Detail

FLOAT

public static final Almost FLOAT
This instance uses default float precision


DOUBLE

public static final Almost DOUBLE
This instance uses default double precision

Constructor Detail

Almost

public Almost()
Accept default precision, appropriate for arithmetic on floats.


Almost

public Almost(double epsilon,
              double minValue)
Specify precision to be used for operations.

Parameters:
epsilon - The smallest positive number that can be added to 1 before the number is considered different from 1. For double precision, use a multiple of MathPlus.DBL_EPSILON. For float precision use a multiple of MathPlus.FLT_EPSILON. I recommend multiplying these values by at least 10 to allow for errors introduced by arithmetic.
minValue - The smallest positive value that should be distinguished from zero. Use a multiple (say 100) of Double.MIN_VALUE or Float.MIN_VALUE.

Almost

public Almost(double epsilon)
Specify precision to be used for operations. MinValue defaults to 100.*Float.MIN_VALUE;

Parameters:
epsilon - The smallest positive number that can be added to 1 before the number is considered different from 1. For float precision use a multiple of 1.192092896e-07. For double precision, use a multiple of 2.2204460492503131e-016; I recommend multiplying these values by at least 10 to allow for errors introduced by arithmetic.

Almost

public Almost(int significantDigits)
Specify precision to be used for operations. Epsilon will be 0.1 to this power. MinValue defaults to 100.*Float.MIN_VALUE;

Parameters:
significantDigits -

Almost

public Almost(boolean isDouble)
Constructor that allows either double or float precision.

Parameters:
isDouble - If true, the precision will be appropriate for a double; if false, a float.
Method Detail

getEpsilon

public double getEpsilon()
Get the smallest positive number that can be added to 1 before the number is considered different from 1.

Returns:
epsilon

getMinValue

public double getMinValue()
Get the smallest positive value that should be distinguished from zero.

Returns:
minValue

between

public boolean between(double x,
                       double x1,
                       double x2)
See if value is between two other values, including almost equality

Parameters:
x - Value to check
x1 - Value at one end of interval.
x2 - Value at other end of interval.
Returns:
true if x is between x1 and x2.

outside

public int outside(double x,
                   double x1,
                   double x2)
See if value is outside two other values.

Parameters:
x - Value to check
x1 - Value at one end of interval.
x2 - Value at other end of interval.
Returns:
Return 0 if x is between x1 and x2, -1 if outside and closer to x1, 1 if outside and closer to x2.

zero

public boolean zero(double r)
See if the number is almost zero

Parameters:
r - A number to check
Returns:
true if the r is almost zero.

equal

public boolean equal(double r1,
                     double r2)
See if two numbers are almost equal.

Parameters:
r1 - First number to check
r2 - Second number to check
Returns:
True if r1 and r2 are almost equal

lt

public boolean lt(double r1,
                  double r2)
Check whether first number is strictly less than second.

Parameters:
r1 - First number to check
r2 - Second number to check
Returns:
true if r1<r2

le

public boolean le(double r1,
                  double r2)
Check whether first number is less than or equal to second.

Parameters:
r1 - First number to check
r2 - Second number to check
Returns:
true if r1<=r2

gt

public boolean gt(double r1,
                  double r2)
Check whether first number is strictly greater than second.

Parameters:
r1 - First number to check
r2 - Second number to check
Returns:
true if r1>r2

ge

public boolean ge(double r1,
                  double r2)
Check whether first number is greater than or equal to second.

Parameters:
r1 - First number to check
r2 - Second number to check
Returns:
true if r1>=r2

cmp

public int cmp(double r1,
               double r2)
Check order of two numbers, within precision.

Parameters:
r1 - First number to check
r2 - Second number to check
Returns:
1 if r1>r2; -1 if r1 < r2; 0 if r1==r2, within precision.

hashCodeOf

public int hashCodeOf(java.lang.Number number,
                      int significantDigits)
Return a hashcode consistent with imprecise floating-point equality. Integers and Longs require exact equality.

Parameters:
number - Number to get hashcode of
significantDigits - Number of significant digits to honor in hashCode
Returns:
new hash code.

hashCodeOf

public int hashCodeOf(java.lang.Number number)
Return a hashcode consistent with imprecise floating-point equality. Integers and Longs require exact equality. The precision is consistent with the value of epsilon.

Parameters:
number - number to get hashcode from
Returns:
hashcode

divide

public double divide(double top,
                     double bottom,
                     boolean limitIsOne)
Safely divide one number by another. Handle zeros and infinity. Never throws floating point exceptions.

Parameters:
top - Numerator
bottom - Denominator
limitIsOne - If true, 0/0 returns 1. If false, 0/0 returns 0.
Returns:
Regular value if arguments are okay. Return +/- 0.01*Float.MAX_VALUE, rather than infinity.

reciprocal

public double reciprocal(double value)
Safely take the reciprocal of a number.

Parameters:
value - Value to take reciprocal of.
Returns:
reciprocal of value

divide

public double divide(double top,
                     double bottom,
                     double limit)
Safely divide one number by another. Handle zeros and infinity. Never throws floating point exceptions.

Parameters:
top - Numerator
bottom - Denominator
limit - This is the returned value for 0/0.
Returns:
Regular value if arguments are okay. Return +/- 0.01*Float.MAX_VALUE, rather than infinity.

compare

public int compare(java.lang.Number n1,
                   java.lang.Number n2)
Specified by:
compare in interface java.util.Comparator<java.lang.Number>

equals

public boolean equals(java.lang.Object object)
Specified by:
equals in interface java.util.Comparator<java.lang.Number>
Overrides:
equals in class java.lang.Object

hashCode

public int hashCode()
Overrides:
hashCode in class java.lang.Object

toString

public java.lang.String toString()
Overrides:
toString in class java.lang.Object