package org.ovirt.engine.ui.common.utils;
/**
* Helper class for working with floating point numbers, such as JavaScript {@code number}
* and its Java {@code double} equivalent.
*/
public class FloatingPointHelper {
/**
* Machine epsilon for JavaScript {@code number} type, lazily initialized to value
* {@code pow(2, -53)}. This number represents an upper bound on the relative error
* due to rounding in floating point arithmetic.
*/
private static double epsilon;
/**
* Returns {@code true} if {@code a} and {@code b} are numerically equal using
* {@linkplain #epsilon machine epsilon} to account for rounding procedure.
*
* @return {@code true} if {@code a} is numerically equal to {@code b}.
*/
public static native boolean epsEqual(Double a, Double b) /*-{
var aValue = a.@java.lang.Double::doubleValue()();
var bValue = b.@java.lang.Double::doubleValue()();
if (!@org.ovirt.engine.ui.common.utils.FloatingPointHelper::epsilon) {
@org.ovirt.engine.ui.common.utils.FloatingPointHelper::epsilon = Math.pow(2, -53);
}
return Math.abs(aValue - bValue) < @org.ovirt.engine.ui.common.utils.FloatingPointHelper::epsilon;
}-*/;
/**
* Compares {@code a} and {@code b} using {@linkplain #epsilon machine epsilon}
* to account for rounding procedure.
*
* @return {@code 0} if {@code a} is numerically equal to {@code b},
* value less than {@code 0} if {@code a} is numerically less than {@code b},
* value greater than {@code 0} if {@code a} is numerically greater than {@code b}.
*/
public static int epsCompare(Double a, Double b) {
if (epsEqual(a, b)) {
return 0;
}
return (a < b) ? -1 : 1;
}
/**
* {@link #epsCompare(Double, Double) epsCompare} method adapted for Float arguments.
* <p>
* In production mode, GWT implements all Java numeric types as JavaScript {@code number}
* so any operations on {@code float} are performed as on {@code double} and will result
* in more-than-expected precision.
*
* @return {@code 0} if {@code a} is numerically equal to {@code b},
* value less than {@code 0} if {@code a} is numerically less than {@code b},
* value greater than {@code 0} if {@code a} is numerically greater than {@code b}.
*/
public static int epsCompare(Float a, Float b) {
return epsCompare(a.doubleValue(), b.doubleValue());
}
}