]> gitweb.fperrin.net Git - GpsPrune.git/blobdiff - tim/prune/jpeg/drew/Rational.java
Version 19, May 2018
[GpsPrune.git] / tim / prune / jpeg / drew / Rational.java
index 3c83b9f5d88595fadb140d4dbb4a82532d6cf495..8395898266677c16593604c8a04a0826db490225 100644 (file)
-package tim.prune.jpeg.drew;\r
-\r
-/**\r
- * Immutable class for holding a rational number without loss of precision.\r
- * Based on Drew Noakes' Metadata extractor at http://drewnoakes.com\r
- */\r
-public class Rational\r
-{\r
-       /** Holds the numerator */\r
-       private final int _numerator;\r
-\r
-       /** Holds the denominator */\r
-       private final int _denominator;\r
-\r
-       /**\r
-        * Constructor\r
-        * @param inNumerator numerator of fraction (upper number)\r
-        * @param inDenominator denominator of fraction (lower number)\r
-        */\r
-       public Rational(int inNumerator, int inDenominator)\r
-       {\r
-               // Could throw exception if denominator is zero\r
-               _numerator = inNumerator;\r
-               _denominator = inDenominator;\r
-       }\r
-\r
-\r
-       /**\r
-        * @return the value of the specified number as a <code>double</code>.\r
-        * This may involve rounding.\r
-        */\r
-       public double doubleValue()\r
-       {\r
-               if (_denominator == 0) return 0.0;\r
-               return (double)_numerator / (double)_denominator;\r
-       }\r
-\r
-       /**\r
-        * @return the value of the specified number as an <code>int</code>.\r
-        * This may involve rounding or truncation.\r
-        */\r
-       public final int intValue()\r
-       {\r
-               if (_denominator == 0) return 0;\r
-               return _numerator / _denominator;\r
-       }\r
-\r
-       /**\r
-        * @return the denominator.\r
-        */\r
-       public final int getDenominator()\r
-       {\r
-               return _denominator;\r
-       }\r
-\r
-       /**\r
-        * @return the numerator.\r
-        */\r
-       public final int getNumerator()\r
-       {\r
-               return _numerator;\r
-       }\r
-\r
-       /**\r
-        * Checks if this rational number is an Integer, either positive or negative\r
-        * @return true if an integer\r
-        */\r
-       public boolean isInteger()\r
-       {\r
-               // number is integer if the denominator is 1, or if the remainder is zero\r
-               return (_denominator == 1\r
-                       || (_denominator != 0 && (_numerator % _denominator == 0)));\r
-       }\r
-\r
-\r
-       /**\r
-        * @return a string representation of the object of form <code>numerator/denominator</code>.\r
-        */\r
-       public String toString()\r
-       {\r
-               return "" + _numerator + "/" + _denominator;\r
-       }\r
-\r
-\r
-       /**\r
-        * Compares two <code>Rational</code> instances, returning true if they are equal\r
-        * @param inOther the Rational to compare this instance to.\r
-        * @return true if instances are equal, otherwise false.\r
-        */\r
-       public boolean equals(Rational inOther)\r
-       {\r
-               // Could also attempt to simplify fractions to lowest common denominator before compare\r
-               return _numerator == inOther._numerator && _denominator == inOther._denominator;\r
-       }\r
-}
\ No newline at end of file
+package tim.prune.jpeg.drew;
+
+/**
+ * Immutable class for holding a rational number without loss of precision.
+ * Based on Drew Noakes' Metadata extractor at https://drewnoakes.com
+ */
+public class Rational
+{
+       /** Holds the numerator */
+       private final long _numerator;
+
+       /** Holds the denominator */
+       private final long _denominator;
+
+       /**
+        * Creates a new (immutable) instance of Rational.
+        */
+       public Rational(long numerator, long denominator)
+       {
+               _numerator = numerator;
+               _denominator = denominator;
+       }
+
+       /**
+        * @return the value of the specified number as a <code>double</code>.
+        * This may involve rounding.
+        */
+       public double doubleValue()
+       {
+               if (_denominator == 0L) return 0.0;
+               return (double)_numerator / (double)_denominator;
+       }
+
+       /**
+        * Returns the value of the specified number as an <code>int</code>.
+        */
+       public final int intValue()
+       {
+               return (int) longValue();
+       }
+
+       /**
+        * Returns the value of the specified number as a <code>long</code>.
+        * This may involve rounding or truncation.
+        * If the denominator is 0, returns 0 to avoid dividing by 0.
+        */
+       public final long longValue()
+       {
+               if (_denominator == 0L) return 0L;
+               return _numerator / _denominator;
+       }
+
+       /** Returns the denominator */
+       public final long getDenominator()
+       {
+               return _denominator;
+       }
+
+       /** Returns the numerator */
+       public final long getNumerator()
+       {
+               return _numerator;
+       }
+
+       /**
+        * @return the value of the specified number as a positive <code>double</code>.
+        * Prevents interpretation of 32 bit numbers as negative, and forces a positive answer.
+        * Needed?
+        */
+       public double convertToPositiveValue()
+       {
+               if (_denominator == 0L) return 0.0;
+               double numeratorDbl = _numerator;
+               double denomDbl = _denominator;
+               if (_numerator >= 0L) {
+                       // Numerator is positive (but maybe denominator isn't?)
+                       return numeratorDbl / denomDbl;
+               }
+               // Add 2^32 to negative doubles to make them positive
+               final double correction = Math.pow(2.0, 32);
+               numeratorDbl += correction;
+               if (_denominator < 0L) {
+                       denomDbl += correction;
+               }
+               return numeratorDbl / denomDbl;
+       }
+
+       /**
+        * Returns a string representation of the object of form <code>numerator/denominator</code>.
+        */
+       @Override
+       public String toString()
+       {
+               return "" + _numerator + "/" + _denominator;
+       }
+
+       /**
+        * Compares two {@link Rational} instances, returning true if they are mathematically
+        * equivalent.
+        *
+        * @param obj the {@link Rational} to compare this instance to.
+        * @return true if instances are mathematically equivalent, otherwise false.  Will also
+        *         give false if <code>obj</code> is not an instance of {@link Rational}.
+        */
+       @Override
+       public boolean equals( Object obj)
+       {
+               if (obj==null || !(obj instanceof Rational))
+                       return false;
+               Rational that = (Rational) obj;
+               return this.doubleValue() == that.doubleValue();
+       }
+}