From 9eba2e72ecba1f33c73d358eb509f0a0816aa810 Mon Sep 17 00:00:00 2001 From: Adrien Hopkins Date: Wed, 16 Oct 2019 14:41:44 -0400 Subject: Added unit prefixes. --- src/org/unitConverter/math/DecimalComparison.java | 67 +++++++++++++++++++++++ 1 file changed, 67 insertions(+) (limited to 'src/org/unitConverter/math/DecimalComparison.java') diff --git a/src/org/unitConverter/math/DecimalComparison.java b/src/org/unitConverter/math/DecimalComparison.java index 7cdbe5b..859e8da 100644 --- a/src/org/unitConverter/math/DecimalComparison.java +++ b/src/org/unitConverter/math/DecimalComparison.java @@ -16,6 +16,8 @@ */ package org.unitConverter.math; +import java.math.BigDecimal; + /** * A class that contains methods to compare float and double values. * @@ -44,6 +46,18 @@ public final class DecimalComparison { /** * Tests for equality of double values using {@link #DOUBLE_EPSILON}. + *

+ * WARNING: this method is not technically transitive. If a and b are off by slightly less than + * {@code epsilon * max(abs(a), abs(b))}, and b and c are off by slightly less than + * {@code epsilon * max(abs(b), abs(c))}, then equals(a, b) and equals(b, c) will both return true, but equals(a, c) + * will return false. However, this situation is very unlikely to ever happen in a real programming situation. + *

+ * If this does become a concern, some ways to solve this problem: + *

    + *
  1. Raise the value of epsilon using {@link #equals(double, double, double)} (this does not make a violation of + * transitivity impossible, it just significantly reduces the chances of it happening) + *
  2. Use {@link BigDecimal} instead of {@code double} (this will make a violation of transitivity 100% impossible) + *
* * @param a * first value to test @@ -52,6 +66,7 @@ public final class DecimalComparison { * @return whether they are equal * @since 2019-03-18 * @since v0.2.0 + * @see #hashCode(double) */ public static final boolean equals(final double a, final double b) { return DecimalComparison.equals(a, b, DOUBLE_EPSILON); @@ -60,6 +75,19 @@ public final class DecimalComparison { /** * Tests for double equality using a custom epsilon value. * + *

+ * WARNING: this method is not technically transitive. If a and b are off by slightly less than + * {@code epsilon * max(abs(a), abs(b))}, and b and c are off by slightly less than + * {@code epsilon * max(abs(b), abs(c))}, then equals(a, b) and equals(b, c) will both return true, but equals(a, c) + * will return false. However, this situation is very unlikely to ever happen in a real programming situation. + *

+ * If this does become a concern, some ways to solve this problem: + *

    + *
  1. Raise the value of epsilon (this does not make a violation of transitivity impossible, it just significantly + * reduces the chances of it happening) + *
  2. Use {@link BigDecimal} instead of {@code double} (this will make a violation of transitivity 100% impossible) + *
+ * * @param a * first value to test * @param b @@ -77,6 +105,19 @@ public final class DecimalComparison { /** * Tests for equality of float values using {@link #FLOAT_EPSILON}. * + *

+ * WARNING: this method is not technically transitive. If a and b are off by slightly less than + * {@code epsilon * max(abs(a), abs(b))}, and b and c are off by slightly less than + * {@code epsilon * max(abs(b), abs(c))}, then equals(a, b) and equals(b, c) will both return true, but equals(a, c) + * will return false. However, this situation is very unlikely to ever happen in a real programming situation. + *

+ * If this does become a concern, some ways to solve this problem: + *

    + *
  1. Raise the value of epsilon using {@link #equals(float, float, float)} (this does not make a violation of + * transitivity impossible, it just significantly reduces the chances of it happening) + *
  2. Use {@link BigDecimal} instead of {@code float} (this will make a violation of transitivity 100% impossible) + *
+ * * @param a * first value to test * @param b @@ -92,6 +133,19 @@ public final class DecimalComparison { /** * Tests for float equality using a custom epsilon value. * + *

+ * WARNING: this method is not technically transitive. If a and b are off by slightly less than + * {@code epsilon * max(abs(a), abs(b))}, and b and c are off by slightly less than + * {@code epsilon * max(abs(b), abs(c))}, then equals(a, b) and equals(b, c) will both return true, but equals(a, c) + * will return false. However, this situation is very unlikely to ever happen in a real programming situation. + *

+ * If this does become a concern, some ways to solve this problem: + *

    + *
  1. Raise the value of epsilon (this does not make a violation of transitivity impossible, it just significantly + * reduces the chances of it happening) + *
  2. Use {@link BigDecimal} instead of {@code float} (this will make a violation of transitivity 100% impossible) + *
+ * * @param a * first value to test * @param b @@ -106,6 +160,19 @@ public final class DecimalComparison { return Math.abs(a - b) <= epsilon * Math.max(Math.abs(a), Math.abs(b)); } + /** + * Takes the hash code of doubles. Values that are equal according to {@link #equals(double, double)} will have the + * same hash code. + * + * @param d + * double to hash + * @return hash code of double + * @since 2019-10-16 + */ + public static final int hash(final double d) { + return Float.hashCode((float) d); + } + // You may NOT get any DecimalComparison instances private DecimalComparison() { throw new AssertionError(); -- cgit v1.2.3