]> gitweb.fperrin.net Git - GpsPrune.git/blob - tim/prune/jpeg/drew/Rational.java
Version 19, May 2018
[GpsPrune.git] / tim / prune / jpeg / drew / Rational.java
1 package tim.prune.jpeg.drew;
2
3 /**
4  * Immutable class for holding a rational number without loss of precision.
5  * Based on Drew Noakes' Metadata extractor at https://drewnoakes.com
6  */
7 public class Rational
8 {
9         /** Holds the numerator */
10         private final long _numerator;
11
12         /** Holds the denominator */
13         private final long _denominator;
14
15         /**
16          * Creates a new (immutable) instance of Rational.
17          */
18         public Rational(long numerator, long denominator)
19         {
20                 _numerator = numerator;
21                 _denominator = denominator;
22         }
23
24         /**
25          * @return the value of the specified number as a <code>double</code>.
26          * This may involve rounding.
27          */
28         public double doubleValue()
29         {
30                 if (_denominator == 0L) return 0.0;
31                 return (double)_numerator / (double)_denominator;
32         }
33
34         /**
35          * Returns the value of the specified number as an <code>int</code>.
36          */
37         public final int intValue()
38         {
39                 return (int) longValue();
40         }
41
42         /**
43          * Returns the value of the specified number as a <code>long</code>.
44          * This may involve rounding or truncation.
45          * If the denominator is 0, returns 0 to avoid dividing by 0.
46          */
47         public final long longValue()
48         {
49                 if (_denominator == 0L) return 0L;
50                 return _numerator / _denominator;
51         }
52
53         /** Returns the denominator */
54         public final long getDenominator()
55         {
56                 return _denominator;
57         }
58
59         /** Returns the numerator */
60         public final long getNumerator()
61         {
62                 return _numerator;
63         }
64
65         /**
66          * @return the value of the specified number as a positive <code>double</code>.
67          * Prevents interpretation of 32 bit numbers as negative, and forces a positive answer.
68          * Needed?
69          */
70         public double convertToPositiveValue()
71         {
72                 if (_denominator == 0L) return 0.0;
73                 double numeratorDbl = _numerator;
74                 double denomDbl = _denominator;
75                 if (_numerator >= 0L) {
76                         // Numerator is positive (but maybe denominator isn't?)
77                         return numeratorDbl / denomDbl;
78                 }
79                 // Add 2^32 to negative doubles to make them positive
80                 final double correction = Math.pow(2.0, 32);
81                 numeratorDbl += correction;
82                 if (_denominator < 0L) {
83                         denomDbl += correction;
84                 }
85                 return numeratorDbl / denomDbl;
86         }
87
88         /**
89          * Returns a string representation of the object of form <code>numerator/denominator</code>.
90          */
91         @Override
92         public String toString()
93         {
94                 return "" + _numerator + "/" + _denominator;
95         }
96
97         /**
98          * Compares two {@link Rational} instances, returning true if they are mathematically
99          * equivalent.
100          *
101          * @param obj the {@link Rational} to compare this instance to.
102          * @return true if instances are mathematically equivalent, otherwise false.  Will also
103          *         give false if <code>obj</code> is not an instance of {@link Rational}.
104          */
105         @Override
106         public boolean equals( Object obj)
107         {
108                 if (obj==null || !(obj instanceof Rational))
109                         return false;
110                 Rational that = (Rational) obj;
111                 return this.doubleValue() == that.doubleValue();
112         }
113 }