You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sis.apache.org by de...@apache.org on 2019/01/24 11:53:48 UTC
[sis] branch geoapi-4.0 updated: Be more careful about which
NumberRange we can cache. This is needed for avoiding to replace NaN bit
patterns by another bit patterns,
since Float.equals(Object) and Double.equals(Object) consider all NaN values
as equal.
This is an automated email from the ASF dual-hosted git repository.
desruisseaux pushed a commit to branch geoapi-4.0
in repository https://gitbox.apache.org/repos/asf/sis.git
The following commit(s) were added to refs/heads/geoapi-4.0 by this push:
new 308bd3b Be more careful about which NumberRange we can cache. This is needed for avoiding to replace NaN bit patterns by another bit patterns, since Float.equals(Object) and Double.equals(Object) consider all NaN values as equal.
308bd3b is described below
commit 308bd3bdcdb232261474dc9526e537106eb97459
Author: Martin Desruisseaux <ma...@geomatys.com>
AuthorDate: Thu Jan 24 12:52:26 2019 +0100
Be more careful about which NumberRange we can cache. This is needed for avoiding to replace NaN bit patterns by another bit patterns, since Float.equals(Object) and Double.equals(Object) consider all NaN values as equal.
---
.../org/apache/sis/measure/MeasurementRange.java | 50 +++++++++-----
.../java/org/apache/sis/measure/NumberRange.java | 76 +++++++++++++---------
.../main/java/org/apache/sis/measure/Range.java | 26 ++++++--
.../main/java/org/apache/sis/util/Emptiable.java | 4 +-
.../org/apache/sis/measure/NumberRangeTest.java | 18 ++---
5 files changed, 110 insertions(+), 64 deletions(-)
diff --git a/core/sis-utility/src/main/java/org/apache/sis/measure/MeasurementRange.java b/core/sis-utility/src/main/java/org/apache/sis/measure/MeasurementRange.java
index 969d6fd..5966f5f 100644
--- a/core/sis-utility/src/main/java/org/apache/sis/measure/MeasurementRange.java
+++ b/core/sis-utility/src/main/java/org/apache/sis/measure/MeasurementRange.java
@@ -79,6 +79,8 @@ public class MeasurementRange<E extends Number & Comparable<? super E>> extends
/**
* Constructs a range of {@code float} values.
+ * The minimum and maximum values can not be NaN but can be infinite.
+ * If the minimum is greater than the maximum, then the range {@linkplain #isEmpty() is empty}.
* This method may return a shared instance, at implementation choice.
*
* @param minValue the minimal value, or {@link Float#NEGATIVE_INFINITY} if none.
@@ -87,17 +89,21 @@ public class MeasurementRange<E extends Number & Comparable<? super E>> extends
* @param isMaxIncluded {@code true} if the maximal value is inclusive, or {@code false} if exclusive.
* @param unit the unit of measurement, or {@code null} if unknown.
* @return the new range of numeric values for the given endpoints and unit of measurement.
+ * @throws IllegalArgumentException if {@link Float#isNaN(float)} is {@code true} for a given value.
*/
public static MeasurementRange<Float> create(float minValue, boolean isMinIncluded,
float maxValue, boolean isMaxIncluded, Unit<?> unit)
{
- return unique(new MeasurementRange<>(Float.class,
- valueOf("minValue", minValue, Float.NEGATIVE_INFINITY), isMinIncluded,
- valueOf("maxValue", maxValue, Float.POSITIVE_INFINITY), isMaxIncluded, unit));
+ final Float min = valueOf("minValue", minValue, Float.NEGATIVE_INFINITY);
+ final Float max = valueOf("maxValue", maxValue, Float.POSITIVE_INFINITY);
+ // No need to test isCacheable(Number) because the type is known and valueOf(…) disallows NaN values.
+ return unique(new MeasurementRange<>(Float.class, min, isMinIncluded, Objects.equals(min, max) ? min : max, isMaxIncluded, unit));
}
/**
* Constructs a range of {@code double} values.
+ * The minimum and maximum values can not be NaN but can be infinite.
+ * If the minimum is greater than the maximum, then the range {@linkplain #isEmpty() is empty}.
* This method may return a shared instance, at implementation choice.
*
* @param minValue the minimal value, or {@link Double#NEGATIVE_INFINITY} if none.
@@ -106,13 +112,15 @@ public class MeasurementRange<E extends Number & Comparable<? super E>> extends
* @param isMaxIncluded {@code true} if the maximal value is inclusive, or {@code false} if exclusive.
* @param unit the unit of measurement, or {@code null} if unknown.
* @return the new range of numeric values for the given endpoints and unit of measurement.
+ * @throws IllegalArgumentException if {@link Double#isNaN(double)} is {@code true} for a given value.
*/
public static MeasurementRange<Double> create(double minValue, boolean isMinIncluded,
double maxValue, boolean isMaxIncluded, Unit<?> unit)
{
- return unique(new MeasurementRange<>(Double.class,
- valueOf("minValue", minValue, Double.NEGATIVE_INFINITY), isMinIncluded,
- valueOf("maxValue", maxValue, Double.POSITIVE_INFINITY), isMaxIncluded, unit));
+ final Double min = valueOf("minValue", minValue, Double.NEGATIVE_INFINITY);
+ final Double max = valueOf("maxValue", maxValue, Double.POSITIVE_INFINITY);
+ // No need to test isCacheable(Number) because the type is known and valueOf(…) disallows NaN values.
+ return unique(new MeasurementRange<>(Double.class, min, isMinIncluded, Objects.equals(min, max) ? min : max, isMaxIncluded, unit));
}
/**
@@ -123,18 +131,20 @@ public class MeasurementRange<E extends Number & Comparable<? super E>> extends
* @param minValue the minimal value (exclusive), or {@link Double#NEGATIVE_INFINITY} if none.
* @param unit the unit of measurement, or {@code null} if unknown.
* @return the new range of numeric values greater than the given value.
+ * @throws IllegalArgumentException if {@link Double#isNaN(double)} is {@code true} for the given value.
*
* @since 0.6
*/
public static MeasurementRange<Double> createGreaterThan(final double minValue, final Unit<?> unit) {
+ // No need to test isCacheable(Number) because the type is known and valueOf(…) disallows NaN values.
return unique(new MeasurementRange<>(Double.class,
valueOf("minValue", minValue, Double.NEGATIVE_INFINITY), false, null, false, unit));
}
/**
* Constructs a range using the smallest type of {@link Number} that can hold the given values.
- * This method performs the same work than {@link NumberRange#createBestFit
- * NumberRange.createBestFit(…)} with an additional {@code unit} argument.
+ * This method performs the same work than {@link NumberRange#createBestFit NumberRange.createBestFit(…)}
+ * with an additional {@code unit} argument.
*
* <p>This method may return a shared instance, at implementation choice.</p>
*
@@ -149,17 +159,22 @@ public class MeasurementRange<E extends Number & Comparable<? super E>> extends
*/
@SuppressWarnings({"rawtypes","unchecked"})
public static MeasurementRange<?> createBestFit(final Number minValue, final boolean isMinIncluded,
- final Number maxValue, final boolean isMaxIncluded, final Unit<?> unit)
+ final Number maxValue, final boolean isMaxIncluded, final Unit<?> unit)
{
- final Class<? extends Number> type = Numbers.widestClass(Numbers.narrowestClass(minValue),
- Numbers.narrowestClass(maxValue));
+ final Class<? extends Number> type;
+ type = Numbers.widestClass(Numbers.narrowestClass(minValue),
+ Numbers.narrowestClass(maxValue));
if (type == null) {
return null;
}
- MeasurementRange range = new MeasurementRange(type,
- Numbers.cast(minValue, type), isMinIncluded,
- Numbers.cast(maxValue, type), isMaxIncluded, unit);
- if (!isOtherNaN(minValue) && !isOtherNaN(maxValue)) {
+ Number min = Numbers.cast(minValue, type);
+ Number max = Numbers.cast(maxValue, type);
+ final boolean isCacheable = isCacheable(min) && isCacheable(max);
+ if (isCacheable && Objects.equals(min, max)) {
+ max = min; // Share the same instance.
+ }
+ MeasurementRange range = new MeasurementRange(type, min, isMinIncluded, max, isMaxIncluded, unit);
+ if (isCacheable) {
range = unique(range);
}
return range;
@@ -454,7 +469,10 @@ public class MeasurementRange<E extends Number & Comparable<? super E>> extends
}
/**
- * Compares this range with the specified object for equality.
+ * Compares this measurement range with the specified object for equality. Two {@code MeasurementRange} instances
+ * are considered equal if they met all conditions {@linkplain Range#equals(Object) documented in the parent class}
+ * and their {@link #unit()} are equal in the sense of {@link Objects#equals(Object, Object)}.
+ * Note that this comparison does not distinguish the various {@link Float#NaN} or {@link Double#NaN} bit patterns.
*
* @return {@inheritDoc}
*/
diff --git a/core/sis-utility/src/main/java/org/apache/sis/measure/NumberRange.java b/core/sis-utility/src/main/java/org/apache/sis/measure/NumberRange.java
index ac117d1..77be12c 100644
--- a/core/sis-utility/src/main/java/org/apache/sis/measure/NumberRange.java
+++ b/core/sis-utility/src/main/java/org/apache/sis/measure/NumberRange.java
@@ -112,7 +112,7 @@ public class NumberRange<E extends Number & Comparable<? super E>> extends Range
* </div>
*
* We use this method only for caching range of wrapper of primitive types ({@link Byte},
- * {@link Short}, <i>etc.</i>) because those type are known to be immutable.
+ * {@link Short}, <i>etc.</i>) because those types are known to be immutable.
*/
static <E extends Number & Comparable<? super E>, T extends NumberRange<E>> T unique(T range) {
if (!range.isEmpty()) {
@@ -122,19 +122,23 @@ public class NumberRange<E extends Number & Comparable<? super E>> extends Range
}
/**
- * Returns {@code true} if the given value is a NaN value other than the canonical {@link Float#NaN}
- * or {@link Double#NaN} value. This is used for determining if the range should be omitted from the
- * {@link POOL} cache, since {@link #equals(Object)} considers all NaN values as equal.
+ * Returns {@code true} if the given value is valid for a range to be cached by {@link #union(Range)}.
+ * A range can be cached if the {@link Number} values are null or instances of a standard Java class
+ * known to be immutable, and the wrapped values are not NaN except the canonical {@link Double#NaN}
+ * or {@link Float#NaN} values. This check is necessary because {@link #equals(Object)} considers all
+ * {@code NaN} values as equal.
*/
- static boolean isOtherNaN(final Number n) {
- if (n instanceof Double) {
+ static boolean isCacheable(final Number n) {
+ if (n == null) {
+ return true;
+ } else if (n instanceof Double) {
final double value = (Double) n;
- return Double.isNaN(value) && Double.doubleToRawLongBits(value) != 0x7ff8000000000000L;
+ return !Double.isNaN(value) || Double.doubleToRawLongBits(value) == 0x7FF8000000000000L;
} else if (n instanceof Float) {
final float value = (Float) n;
- return Float.isNaN(value) && Float.floatToRawIntBits(value) != 0x7fc00000;
+ return !Float.isNaN(value) || Float.floatToRawIntBits(value) == 0x7FC00000;
} else {
- return false;
+ return Numbers.getEnumConstant(n.getClass()) != Numbers.OTHER;
}
}
@@ -152,7 +156,7 @@ public class NumberRange<E extends Number & Comparable<? super E>> extends Range
*/
public static <N extends Number & Comparable<? super N>> NumberRange<N> create(final Class<N> type, final N value) {
NumberRange<N> range = new NumberRange<>(type, value, true, value, true);
- if (!isOtherNaN(value)) {
+ if (isCacheable(value)) {
range = unique(range);
}
return range;
@@ -160,6 +164,7 @@ public class NumberRange<E extends Number & Comparable<? super E>> extends Range
/**
* Constructs a range of {@code byte} values.
+ * If the minimum is greater than the maximum, then the range {@linkplain #isEmpty() is empty}.
* This method may return a shared instance, at implementation choice.
*
* @param minValue the minimal value.
@@ -179,6 +184,7 @@ public class NumberRange<E extends Number & Comparable<? super E>> extends Range
/**
* Constructs a range of {@code short} values.
+ * If the minimum is greater than the maximum, then the range {@linkplain #isEmpty() is empty}.
* This method may return a shared instance, at implementation choice.
*
* @param minValue the minimal value.
@@ -197,6 +203,7 @@ public class NumberRange<E extends Number & Comparable<? super E>> extends Range
/**
* Constructs a range of {@code int} values.
+ * If the minimum is greater than the maximum, then the range {@linkplain #isEmpty() is empty}.
* This method may return a shared instance, at implementation choice.
*
* @param minValue the minimal value.
@@ -217,6 +224,7 @@ public class NumberRange<E extends Number & Comparable<? super E>> extends Range
/**
* Constructs a range of {@code long} values.
+ * If the minimum is greater than the maximum, then the range {@linkplain #isEmpty() is empty}.
* This method may return a shared instance, at implementation choice.
*
* @param minValue the minimal value.
@@ -235,7 +243,8 @@ public class NumberRange<E extends Number & Comparable<? super E>> extends Range
/**
* Constructs a range of {@code float} values.
- * The values can not be {@link Float#NaN}.
+ * The minimum and maximum values can not be NaN but can be infinite.
+ * If the minimum is greater than the maximum, then the range {@linkplain #isEmpty() is empty}.
* This method may return a shared instance, at implementation choice.
*
* @param minValue the minimal value, or {@link Float#NEGATIVE_INFINITY} if none.
@@ -243,13 +252,15 @@ public class NumberRange<E extends Number & Comparable<? super E>> extends Range
* @param maxValue the maximal value, or {@link Float#POSITIVE_INFINITY} if none.
* @param isMaxIncluded {@code true} if the maximal value is inclusive, or {@code false} if exclusive.
* @return the new range of numeric values for the given endpoints.
+ * @throws IllegalArgumentException if {@link Float#isNaN(float)} is {@code true} for a given value.
*/
public static NumberRange<Float> create(final float minValue, final boolean isMinIncluded,
final float maxValue, final boolean isMaxIncluded)
{
- return unique(new NumberRange<>(Float.class,
- valueOf("minValue", minValue, Float.NEGATIVE_INFINITY), isMinIncluded,
- valueOf("maxValue", maxValue, Float.POSITIVE_INFINITY), isMaxIncluded));
+ final Float min = valueOf("minValue", minValue, Float.NEGATIVE_INFINITY);
+ final Float max = valueOf("maxValue", maxValue, Float.POSITIVE_INFINITY);
+ // No need to test isCacheable(Number) because the type is known and valueOf(…) disallows NaN values.
+ return unique(new NumberRange<>(Float.class, min, isMinIncluded, Objects.equals(min, max) ? min : max, isMaxIncluded));
}
/**
@@ -265,7 +276,8 @@ public class NumberRange<E extends Number & Comparable<? super E>> extends Range
/**
* Constructs a range of {@code double} values.
- * The values can not be {@link Double#NaN}.
+ * The minimum and maximum values can not be NaN but can be infinite.
+ * If the minimum is greater than the maximum, then the range {@linkplain #isEmpty() is empty}.
* This method may return a shared instance, at implementation choice.
*
* @param minValue the minimal value, or {@link Double#NEGATIVE_INFINITY} if none.
@@ -273,13 +285,15 @@ public class NumberRange<E extends Number & Comparable<? super E>> extends Range
* @param maxValue the maximal value, or {@link Double#POSITIVE_INFINITY} if none.
* @param isMaxIncluded {@code true} if the maximal value is inclusive, or {@code false} if exclusive.
* @return the new range of numeric values for the given endpoints.
+ * @throws IllegalArgumentException if {@link Double#isNaN(double)} is {@code true} for a given value.
*/
public static NumberRange<Double> create(final double minValue, final boolean isMinIncluded,
final double maxValue, final boolean isMaxIncluded)
{
- return unique(new NumberRange<>(Double.class,
- valueOf("minValue", minValue, Double.NEGATIVE_INFINITY), isMinIncluded,
- valueOf("maxValue", maxValue, Double.POSITIVE_INFINITY), isMaxIncluded));
+ final Double min = valueOf("minValue", minValue, Double.NEGATIVE_INFINITY);
+ final Double max = valueOf("maxValue", maxValue, Double.POSITIVE_INFINITY);
+ // No need to test isCacheable(Number) because the type is known and valueOf(…) disallows NaN values.
+ return unique(new NumberRange<>(Double.class, min, isMinIncluded, Objects.equals(min, max) ? min : max, isMaxIncluded));
}
/**
@@ -324,15 +338,20 @@ public class NumberRange<E extends Number & Comparable<? super E>> extends Range
public static NumberRange<?> createBestFit(final Number minValue, final boolean isMinIncluded,
final Number maxValue, final boolean isMaxIncluded)
{
- final Class<? extends Number> type = Numbers.widestClass(
- Numbers.narrowestClass(minValue), Numbers.narrowestClass(maxValue));
+ final Class<? extends Number> type;
+ type = Numbers.widestClass(Numbers.narrowestClass(minValue),
+ Numbers.narrowestClass(maxValue));
if (type == null) {
return null;
}
- final Number min = Numbers.cast(minValue, type);
- final Number max = Objects.equals(minValue, maxValue) ? min : Numbers.cast(maxValue, type);
+ Number min = Numbers.cast(minValue, type);
+ Number max = Numbers.cast(maxValue, type);
+ final boolean isCacheable = isCacheable(min) && isCacheable(max);
+ if (isCacheable && Objects.equals(min, max)) {
+ max = min; // Share the same instance.
+ }
NumberRange range = new NumberRange(type, min, isMinIncluded, max, isMaxIncluded);
- if (!isOtherNaN(min) && !isOtherNaN(max)) {
+ if (isCacheable) {
range = unique(range);
}
return range;
@@ -356,7 +375,8 @@ public class NumberRange<E extends Number & Comparable<? super E>> extends Range
* @since 0.5
*/
public static NumberRange<Integer> createLeftBounded(final int minValue, final boolean isMinIncluded) {
- return unique(new NumberRange<>(Integer.class, Integer.valueOf(minValue), isMinIncluded, null, false));
+ // Use POOL.unique(…) directly because we do not need the check for Range.isEmpty() here.
+ return POOL.unique(new NumberRange<>(Integer.class, Integer.valueOf(minValue), isMinIncluded, null, false));
}
/**
@@ -459,9 +479,7 @@ public class NumberRange<E extends Number & Comparable<? super E>> extends Range
*/
@SuppressWarnings("unchecked")
<N extends Number & Comparable<? super N>>
- NumberRange<N> convertAndCast(final NumberRange<?> range, final Class<N> type)
- throws IllegalArgumentException
- {
+ NumberRange<N> convertAndCast(final NumberRange<?> range, final Class<N> type) throws IllegalArgumentException {
if (range.elementType == type) {
return (NumberRange<N>) range;
}
@@ -480,9 +498,7 @@ public class NumberRange<E extends Number & Comparable<? super E>> extends Range
* @throws IllegalArgumentException if the given type is not one of the primitive wrappers for numeric types.
*/
@SuppressWarnings("unchecked")
- public <N extends Number & Comparable<? super N>> NumberRange<N> castTo(final Class<N> type)
- throws IllegalArgumentException
- {
+ public <N extends Number & Comparable<? super N>> NumberRange<N> castTo(final Class<N> type) throws IllegalArgumentException {
if (elementType == type) {
return (NumberRange<N>) this;
}
diff --git a/core/sis-utility/src/main/java/org/apache/sis/measure/Range.java b/core/sis-utility/src/main/java/org/apache/sis/measure/Range.java
index 32ae059..edf0c3f 100644
--- a/core/sis-utility/src/main/java/org/apache/sis/measure/Range.java
+++ b/core/sis-utility/src/main/java/org/apache/sis/measure/Range.java
@@ -130,6 +130,7 @@ public class Range<E extends Comparable<? super E>> implements CheckedContainer<
/**
* Creates a new range bounded by the given endpoint values.
+ * If the given minimum value is greater than the maximum value, then the range {@linkplain #isEmpty() is empty}.
*
* <div class="note"><b>Assertion:</b>
* This constructor verifies the {@code minValue} and {@code maxValue} arguments type if Java assertions
@@ -263,7 +264,7 @@ public class Range<E extends Comparable<? super E>> implements CheckedContainer<
/**
* Returns {@code true} if this range is empty. A range is empty if the
- * {@linkplain #getMinValue() minimum value} is smaller than the
+ * {@linkplain #getMinValue() minimum value} is greater than the
* {@linkplain #getMaxValue() maximum value}, or if they are equal while
* at least one of them is exclusive.
*
@@ -582,16 +583,27 @@ public class Range<E extends Comparable<? super E>> implements CheckedContainer<
/**
* Compares this range with the given object for equality.
- * Two ranges are considered equal if they have the same {@link #getElementType() element type} and:
+ * Two ranges are considered equal if they met the following conditions:
*
* <ul>
- * <li>are both {@linkplain #isEmpty() empty}, or</li>
- * <li>have equal {@linkplain #getMinValue() minimum} and {@linkplain #getMaxValue() maximum} values
- * with equal inclusive/exclusive flags. Note that numbers in {@link Float} or {@link Double}
- * wrappers consider all {@code NaN} values as equal.</li>
+ * <li>They are of the same {@linkplain #getClass() class}.</li>
+ * <li>They have the same {@linkplain #getElementType() element type}.</li>
+ * <li>Both ranges {@linkplain #isEmpty() are empty}, <strong>or</strong> (if at least one range is non-empty):
+ * <ul>
+ * <li>They have equal {@linkplain #getMinValue() minimum} value in the sense of {@link Object#equals(Object)}.</li>
+ * <li>They have equal {@linkplain #getMaxValue() maximum} value in the sense of {@link Object#equals(Object)}.</li>
+ * <li>They have equal {@linkplain #isMinIncluded() inclusive minimum} flag.</li>
+ * <li>They have equal {@linkplain #isMaxIncluded() inclusive maximum} flag.</li>
+ * </ul>
+ * <li>Any other requirement added by subclasses.
+ * In particular {@link MeasurementRange} compares also the units of measurement.</li>
* </ul>
*
- * Subclasses may add other requirements, for example on units of measurement.
+ * Note that this method may return {@code true} even if the bounds are not strictly identical.
+ * In particular this method returns {@code true} if the ranges are empty regardless their minimum and maximum values,
+ * and also returns {@code true} if the bounds are wrappers for some {@link Float#NaN} or {@link Double#NaN} values
+ * even if their {@linkplain Double#doubleToRawLongBits(double) raw bits pattern} are not the same.
+ * The later is because {@link Float#equals(Object)} and {@link Double#equals(Object)} consider all NaN values as equal.
*
* @param object the object to compare with this range for equality.
* @return {@code true} if the given object is equal to this range.
diff --git a/core/sis-utility/src/main/java/org/apache/sis/util/Emptiable.java b/core/sis-utility/src/main/java/org/apache/sis/util/Emptiable.java
index 41d1bc1..6d3171e 100644
--- a/core/sis-utility/src/main/java/org/apache/sis/util/Emptiable.java
+++ b/core/sis-utility/src/main/java/org/apache/sis/util/Emptiable.java
@@ -19,7 +19,7 @@ package org.apache.sis.util;
/**
* Interface of classes for which empty instances may exist.
- * This interface is typically used for filtering empty elements from a collection or a tree of objects.
+ * This interface is typically used for filtering empty elements from a tree of objects.
* Some examples of emptiable classes are:
*
* <ul>
@@ -33,7 +33,7 @@ package org.apache.sis.util;
*
* SIS collections do <strong>not</strong> implement this interface even if they provide a {@code isEmpty()} method,
* for consistency with collections in {@code java.util} and other libraries. This policy avoid duplicated calls to
- * {@code isEmpty()} methods when the caller need to check for both {@code Collection} and {@code Emptiable} interfaces.
+ * {@code isEmpty()} methods when the caller needs to check for both {@code Collection} and {@code Emptiable} interfaces.
*
* @author Martin Desruisseaux (Geomatys)
* @version 0.4
diff --git a/core/sis-utility/src/test/java/org/apache/sis/measure/NumberRangeTest.java b/core/sis-utility/src/test/java/org/apache/sis/measure/NumberRangeTest.java
index f9a381d..ce5b83b 100644
--- a/core/sis-utility/src/test/java/org/apache/sis/measure/NumberRangeTest.java
+++ b/core/sis-utility/src/test/java/org/apache/sis/measure/NumberRangeTest.java
@@ -38,17 +38,17 @@ import static org.junit.Assert.*;
})
public final strictfp class NumberRangeTest extends TestCase {
/**
- * Tests {@link NumberRange#isOtherNaN(Number)}.
+ * Tests {@link NumberRange#isCacheable(Number)}.
*/
@Test
- public void testIsOtherNaN() {
- assertFalse(NumberRange.isOtherNaN(0));
- assertFalse(NumberRange.isOtherNaN(0f));
- assertFalse(NumberRange.isOtherNaN(0d));
- assertFalse(NumberRange.isOtherNaN(Float.NaN));
- assertFalse(NumberRange.isOtherNaN(Double.NaN));
- assertFalse(NumberRange.isOtherNaN(MathFunctions.toNanFloat(0)));
- assertTrue (NumberRange.isOtherNaN(MathFunctions.toNanFloat(1)));
+ public void testIsCacheable() {
+ assertTrue (NumberRange.isCacheable(0));
+ assertTrue (NumberRange.isCacheable(0f));
+ assertTrue (NumberRange.isCacheable(0d));
+ assertTrue (NumberRange.isCacheable(Float.NaN));
+ assertTrue (NumberRange.isCacheable(Double.NaN));
+ assertTrue (NumberRange.isCacheable(MathFunctions.toNanFloat(0)));
+ assertFalse(NumberRange.isCacheable(MathFunctions.toNanFloat(1)));
}
/**