X-Git-Url: http://gitweb.fperrin.net/?p=GpsPrune.git;a=blobdiff_plain;f=src%2Ftim%2Fprune%2Fjpeg%2Fdrew%2FRational.java;fp=src%2Ftim%2Fprune%2Fjpeg%2Fdrew%2FRational.java;h=8395898266677c16593604c8a04a0826db490225;hp=0000000000000000000000000000000000000000;hb=ce6f2161b8596f7018d6a76bff79bc9e571f35fd;hpb=2d8cb72e84d5cc1089ce77baf1e34ea3ea2f8465 diff --git a/src/tim/prune/jpeg/drew/Rational.java b/src/tim/prune/jpeg/drew/Rational.java new file mode 100644 index 0000000..8395898 --- /dev/null +++ b/src/tim/prune/jpeg/drew/Rational.java @@ -0,0 +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 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(); + } +}