X-Git-Url: https://gitweb.fperrin.net/?p=GpsPrune.git;a=blobdiff_plain;f=tim%2Fprune%2Fjpeg%2Fdrew%2FRational.java;h=8395898266677c16593604c8a04a0826db490225;hp=3c83b9f5d88595fadb140d4dbb4a82532d6cf495;hb=92dad5df664287acb51728e9ea599f150765d34a;hpb=81843c3d8d0771bf00d0f26034a13aa515465c78 diff --git a/tim/prune/jpeg/drew/Rational.java b/tim/prune/jpeg/drew/Rational.java index 3c83b9f..8395898 100644 --- a/tim/prune/jpeg/drew/Rational.java +++ b/tim/prune/jpeg/drew/Rational.java @@ -1,95 +1,113 @@ -package tim.prune.jpeg.drew; - -/** - * Immutable class for holding a rational number without loss of precision. - * Based on Drew Noakes' Metadata extractor at http://drewnoakes.com - */ -public class Rational -{ - /** Holds the numerator */ - private final int _numerator; - - /** Holds the denominator */ - private final int _denominator; - - /** - * Constructor - * @param inNumerator numerator of fraction (upper number) - * @param inDenominator denominator of fraction (lower number) - */ - public Rational(int inNumerator, int inDenominator) - { - // Could throw exception if denominator is zero - _numerator = inNumerator; - _denominator = inDenominator; - } - - - /** - * @return the value of the specified number as a double. - * This may involve rounding. - */ - public double doubleValue() - { - if (_denominator == 0) return 0.0; - return (double)_numerator / (double)_denominator; - } - - /** - * @return the value of the specified number as an int. - * This may involve rounding or truncation. - */ - public final int intValue() - { - if (_denominator == 0) return 0; - return _numerator / _denominator; - } - - /** - * @return the denominator. - */ - public final int getDenominator() - { - return _denominator; - } - - /** - * @return the numerator. - */ - public final int getNumerator() - { - return _numerator; - } - - /** - * Checks if this rational number is an Integer, either positive or negative - * @return true if an integer - */ - public boolean isInteger() - { - // number is integer if the denominator is 1, or if the remainder is zero - return (_denominator == 1 - || (_denominator != 0 && (_numerator % _denominator == 0))); - } - - - /** - * @return a string representation of the object of form numerator/denominator. - */ - public String toString() - { - return "" + _numerator + "/" + _denominator; - } - - - /** - * Compares two Rational instances, returning true if they are equal - * @param inOther the Rational to compare this instance to. - * @return true if instances are equal, otherwise false. - */ - public boolean equals(Rational inOther) - { - // Could also attempt to simplify fractions to lowest common denominator before compare - return _numerator == inOther._numerator && _denominator == inOther._denominator; - } -} \ 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 double. + * 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 int. + */ + public final int intValue() + { + return (int) longValue(); + } + + /** + * Returns the value of the specified number as a long. + * 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 double. + * 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 numerator/denominator. + */ + @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 obj 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(); + } +}