Changeset 6127 in josm for trunk/src/com/drew/lang/Rational.java
- Timestamp:
- 2013-08-09T18:05:11+02:00 (11 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/com/drew/lang/Rational.java
r4231 r6127 1 1 /* 2 * Rational.java 3 * 4 * This class is public domain software - that is, you can do whatever you want 5 * with it, and include it software that is licensed under the GNU or the 6 * BSD license, or whatever other licence you choose, including proprietary 7 * closed source licenses. Similarly, I release this Java version under the 8 * same license, though I do ask that you leave this header in tact. 9 * 10 * If you make modifications to this code that you think would benefit the 11 * wider community, please send me a copy and I'll post it on my site. 12 * 13 * If you make use of this code, I'd appreciate hearing about it. 14 * drew.noakes@drewnoakes.com 15 * Latest version of this software kept at 16 * http://drewnoakes.com/ 17 * 18 * Created on 6 May 2002, 18:06 19 * Updated 26 Aug 2002 by Drew 20 * - Added toSimpleString() method, which returns a simplified and hopefully more 21 * readable version of the Rational. i.e. 2/10 -> 1/5, and 10/2 -> 5 22 * Modified 29 Oct 2002 (v1.2) 23 * - Improved toSimpleString() to factor more complex rational numbers into 24 * a simpler form 25 * i.e. 26 * 10/15 -> 2/3 27 * - toSimpleString() now accepts a boolean flag, 'allowDecimals' which will 28 * display the rational number in decimal form if it fits within 5 digits 29 * i.e. 30 * 3/4 -> 0.75 when allowDecimal == true 2 * Copyright 2002-2012 Drew Noakes 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 * 16 * More information about this project is available at: 17 * 18 * http://drewnoakes.com/code/exif/ 19 * http://code.google.com/p/metadata-extractor/ 31 20 */ 32 21 33 22 package com.drew.lang; 23 24 import com.drew.lang.annotations.NotNull; 25 import com.drew.lang.annotations.Nullable; 34 26 35 27 import java.io.Serializable; … … 38 30 * Immutable class for holding a rational number without loss of precision. Provides 39 31 * a familiar representation via toString() in form <code>numerator/denominator</code>. 40 * <p>41 * @author 32 * 33 * @author Drew Noakes http://drewnoakes.com 42 34 */ 43 35 public class Rational extends java.lang.Number implements Serializable 44 36 { 45 /** 46 * Holds the numerator. 47 */ 48 private final int numerator; 49 50 /** 51 * Holds the denominator. 52 */ 53 private final int denominator; 54 55 private int maxSimplificationCalculations = 1000; 37 private static final long serialVersionUID = 510688928138848770L; 38 39 /** Holds the numerator. */ 40 private final long _numerator; 41 42 /** Holds the denominator. */ 43 private final long _denominator; 56 44 57 45 /** … … 60 48 * with them! 61 49 */ 62 public Rational( int numerator, intdenominator)63 { 64 this.numerator = numerator;65 this.denominator = denominator;50 public Rational(long numerator, long denominator) 51 { 52 _numerator = numerator; 53 _denominator = denominator; 66 54 } 67 55 … … 70 58 * This may involve rounding. 71 59 * 72 * @return 73 * 60 * @return the numeric value represented by this object after conversion 61 * to type <code>double</code>. 74 62 */ 75 63 public double doubleValue() 76 64 { 77 return (double) numerator / (double)denominator;65 return (double) _numerator / (double) _denominator; 78 66 } 79 67 … … 82 70 * This may involve rounding. 83 71 * 84 * @return 85 * 72 * @return the numeric value represented by this object after conversion 73 * to type <code>float</code>. 86 74 */ 87 75 public float floatValue() 88 76 { 89 return (float) numerator / (float)denominator;77 return (float) _numerator / (float) _denominator; 90 78 } 91 79 … … 95 83 * casts the result of <code>doubleValue()</code> to <code>byte</code>. 96 84 * 97 * @return 98 * 85 * @return the numeric value represented by this object after conversion 86 * to type <code>byte</code>. 99 87 */ 100 88 public final byte byteValue() 101 89 { 102 return (byte) doubleValue();90 return (byte) doubleValue(); 103 91 } 104 92 … … 108 96 * casts the result of <code>doubleValue()</code> to <code>int</code>. 109 97 * 110 * @return 111 * 98 * @return the numeric value represented by this object after conversion 99 * to type <code>int</code>. 112 100 */ 113 101 public final int intValue() 114 102 { 115 return (int) doubleValue();103 return (int) doubleValue(); 116 104 } 117 105 … … 121 109 * casts the result of <code>doubleValue()</code> to <code>long</code>. 122 110 * 123 * @return 124 * 111 * @return the numeric value represented by this object after conversion 112 * to type <code>long</code>. 125 113 */ 126 114 public final long longValue() 127 115 { 128 return (long) doubleValue();116 return (long) doubleValue(); 129 117 } 130 118 … … 134 122 * casts the result of <code>doubleValue()</code> to <code>short</code>. 135 123 * 136 * @return 137 * 124 * @return the numeric value represented by this object after conversion 125 * to type <code>short</code>. 138 126 */ 139 127 public final short shortValue() 140 128 { 141 return (short)doubleValue(); 142 } 143 144 145 /** 146 * Returns the denominator. 147 */ 148 public final int getDenominator() 149 { 150 return this.denominator; 151 } 152 153 /** 154 * Returns the numerator. 155 */ 156 public final int getNumerator() 157 { 158 return this.numerator; 159 } 160 161 /** 162 * Returns the reciprocal value of this obejct as a new Rational. 129 return (short) doubleValue(); 130 } 131 132 133 /** Returns the denominator. */ 134 public final long getDenominator() 135 { 136 return this._denominator; 137 } 138 139 /** Returns the numerator. */ 140 public final long getNumerator() 141 { 142 return this._numerator; 143 } 144 145 /** 146 * Returns the reciprocal value of this object as a new Rational. 147 * 163 148 * @return the reciprocal in a new object 164 149 */ 150 @NotNull 165 151 public Rational getReciprocal() 166 152 { 167 return new Rational(this.denominator, this.numerator); 168 } 169 170 /** 171 * Checks if this rational number is an Integer, either positive or negative. 172 */ 153 return new Rational(this._denominator, this._numerator); 154 } 155 156 /** Checks if this rational number is an Integer, either positive or negative. */ 173 157 public boolean isInteger() 174 158 { 175 if (denominator == 1 || 176 (denominator != 0 && (numerator % denominator == 0)) || 177 (denominator == 0 && numerator == 0) 178 ) { 179 return true; 180 } else { 181 return false; 182 } 159 return _denominator == 1 || 160 (_denominator != 0 && (_numerator % _denominator == 0)) || 161 (_denominator == 0 && _numerator == 0); 183 162 } 184 163 185 164 /** 186 165 * Returns a string representation of the object of form <code>numerator/denominator</code>. 187 * @return a string representation of the object. 188 */ 166 * 167 * @return a string representation of the object. 168 */ 169 @NotNull 189 170 public String toString() 190 171 { 191 return numerator + "/" + denominator; 192 } 193 194 /** 195 * Returns the simplest represenation of this Rational's value possible. 196 */ 172 return _numerator + "/" + _denominator; 173 } 174 175 /** Returns the simplest representation of this Rational's value possible. */ 176 @NotNull 197 177 public String toSimpleString(boolean allowDecimal) 198 178 { 199 if ( denominator == 0 &&numerator != 0) {179 if (_denominator == 0 && _numerator != 0) { 200 180 return toString(); 201 181 } else if (isInteger()) { 202 182 return Integer.toString(intValue()); 203 } else if ( numerator != 1 && denominator %numerator == 0) {183 } else if (_numerator != 1 && _denominator % _numerator == 0) { 204 184 // common factor between denominator and numerator 205 int newDenominator = denominator /numerator;185 long newDenominator = _denominator / _numerator; 206 186 return new Rational(1, newDenominator).toSimpleString(allowDecimal); 207 187 } else { … … 220 200 * Decides whether a brute-force simplification calculation should be avoided 221 201 * by comparing the maximum number of possible calculations with some threshold. 202 * 222 203 * @return true if the simplification should be performed, otherwise false 223 204 */ 224 205 private boolean tooComplexForSimplification() 225 206 { 226 double maxPossibleCalculations = (((double)(Math.min(denominator, numerator) - 1) / 5d) + 2); 207 double maxPossibleCalculations = (((double) (Math.min(_denominator, _numerator) - 1) / 5d) + 2); 208 final int maxSimplificationCalculations = 1000; 227 209 return maxPossibleCalculations > maxSimplificationCalculations; 228 210 } … … 231 213 * Compares two <code>Rational</code> instances, returning true if they are mathematically 232 214 * equivalent. 215 * 233 216 * @param obj the Rational to compare this instance to. 234 217 * @return true if instances are mathematically equivalent, otherwise false. Will also 235 218 * return false if <code>obj</code> is not an instance of <code>Rational</code>. 236 219 */ 237 public boolean equals(Object obj) 238 { 239 if (!(obj instanceof Rational)) { 220 @Override 221 public boolean equals(@Nullable Object obj) 222 { 223 if (obj==null || !(obj instanceof Rational)) 240 224 return false; 241 } 242 Rational that = (Rational)obj; 225 Rational that = (Rational) obj; 243 226 return this.doubleValue() == that.doubleValue(); 227 } 228 229 @Override 230 public int hashCode() 231 { 232 return (23 * (int)_denominator) + (int)_numerator; 244 233 } 245 234 … … 252 241 * To reduce a rational, need to see if both numerator and denominator are divisible 253 242 * by a common factor. Using the prime number series in ascending order guarantees 254 * the minimu nnumber of checks required.</p>243 * the minimum number of checks required.</p> 255 244 * <p> 256 245 * However, generating the prime number series seems to be a hefty task. Perhaps … … 265 254 * -- * ------------------------------------ + 2 266 255 * 10 2 267 * 256 * <p/> 268 257 * Math.min(denominator, numerator) - 1 269 258 * = ------------------------------------ + 2 270 259 * 5 271 260 * </pre></code> 272 * @return a simplified instance, or if the Rational could not be simpliffied, 261 * 262 * @return a simplified instance, or if the Rational could not be simplified, 273 263 * returns itself (unchanged) 274 264 */ 265 @NotNull 275 266 public Rational getSimplifiedInstance() 276 267 { … … 278 269 return this; 279 270 } 280 for (int factor = 2; factor <= Math.min( denominator,numerator); factor++) {271 for (int factor = 2; factor <= Math.min(_denominator, _numerator); factor++) { 281 272 if ((factor % 2 == 0 && factor > 2) || (factor % 5 == 0 && factor > 5)) { 282 273 continue; 283 274 } 284 if ( denominator % factor == 0 &&numerator % factor == 0) {275 if (_denominator % factor == 0 && _numerator % factor == 0) { 285 276 // found a common factor 286 return new Rational( numerator / factor,denominator / factor);277 return new Rational(_numerator / factor, _denominator / factor); 287 278 } 288 279 }
Note:
See TracChangeset
for help on using the changeset viewer.