~ubuntu-branches/ubuntu/quantal/commons-math/quantal

« back to all changes in this revision

Viewing changes to src/main/java/org/apache/commons/math/fraction/Fraction.java

  • Committer: Bazaar Package Importer
  • Author(s): Damien Raude-Morvan
  • Date: 2010-04-05 23:33:02 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20100405233302-gpqlceked76nw28a
Tags: 2.1-1
* New upstream release.
* Bump Standards-Version to 3.8.4: no changes needed
* Bump debhelper to >= 7
* Switch to 3.0 (quilt) source format:
  - Remove B-D on quilt
  - Add d/source/format
  - Remove d/README.source

Show diffs side-by-side

added added

removed removed

Lines of Context:
27
27
 * Representation of a rational number.
28
28
 *
29
29
 * implements Serializable since 2.0
30
 
 * 
 
30
 *
31
31
 * @since 1.1
32
 
 * @version $Revision: 795903 $ $Date: 2009-07-20 12:29:46 -0400 (Mon, 20 Jul 2009) $
 
32
 * @version $Revision: 922715 $ $Date: 2010-03-13 20:38:14 -0500 (Sat, 13 Mar 2010) $
33
33
 */
34
34
public class Fraction
35
35
    extends Number
77
77
    /** A fraction representing "-1 / 1". */
78
78
    public static final Fraction MINUS_ONE = new Fraction(-1, 1);
79
79
 
 
80
    /** Message for zero denominator. */
 
81
    private static final String ZERO_DENOMINATOR_MESSAGE =
 
82
        "zero denominator in fraction {0}/{1}";
 
83
 
 
84
    /** Message for overflow. */
 
85
    private static final String OVERFLOW_MESSAGE =
 
86
        "overflow in fraction {0}/{1}, cannot negate";
 
87
 
 
88
    /** Message for null fraction. */
 
89
    private static final String NULL_FRACTION =
 
90
        "null fraction";
 
91
 
80
92
    /** Serializable version identifier */
81
93
    private static final long serialVersionUID = 3698073679419233275L;
82
94
 
83
95
    /** The denominator. */
84
96
    private final int denominator;
85
 
    
 
97
 
86
98
    /** The numerator. */
87
99
    private final int numerator;
88
100
 
206
218
            if ((p2 > overflow) || (q2 > overflow)) {
207
219
                throw new FractionConversionException(value, p2, q2);
208
220
            }
209
 
            
 
221
 
210
222
            double convergent = (double)p2 / (double)q2;
211
223
            if (n < maxIterations && Math.abs(convergent - value) > epsilon && q2 < maxDenominator) {
212
224
                p0 = p1;
223
235
        if (n >= maxIterations) {
224
236
            throw new FractionConversionException(value, maxIterations);
225
237
        }
226
 
        
 
238
 
227
239
        if (q2 < maxDenominator) {
228
240
            this.numerator = (int) p2;
229
241
            this.denominator = (int) q2;
233
245
        }
234
246
 
235
247
    }
236
 
    
 
248
 
237
249
    /**
238
 
     * Create a fraction from an int. 
 
250
     * Create a fraction from an int.
239
251
     * The fraction is num / 1.
240
252
     * @param num the numerator.
241
253
     */
242
254
    public Fraction(int num) {
243
255
        this(num, 1);
244
256
    }
245
 
    
 
257
 
246
258
    /**
247
259
     * Create a fraction given the numerator and denominator.  The fraction is
248
260
     * reduced to lowest terms.
252
264
     */
253
265
    public Fraction(int num, int den) {
254
266
        if (den == 0) {
255
 
            throw MathRuntimeException.createArithmeticException("zero denominator in fraction {0}/{1}",
256
 
                                                                 num, den);
 
267
            throw MathRuntimeException.createArithmeticException(
 
268
                  ZERO_DENOMINATOR_MESSAGE, num, den);
257
269
        }
258
270
        if (den < 0) {
259
271
            if (num == Integer.MIN_VALUE || den == Integer.MIN_VALUE) {
260
 
                throw MathRuntimeException.createArithmeticException("overflow in fraction {0}/{1}, cannot negate",
261
 
                                                                     num, den);
 
272
                throw MathRuntimeException.createArithmeticException(
 
273
                      OVERFLOW_MESSAGE, num, den);
262
274
            }
263
275
            num = -num;
264
276
            den = -den;
269
281
            num /= d;
270
282
            den /= d;
271
283
        }
272
 
        
 
284
 
273
285
        // move sign to numerator.
274
286
        if (den < 0) {
275
287
            num = -num;
278
290
        this.numerator   = num;
279
291
        this.denominator = den;
280
292
    }
281
 
    
 
293
 
282
294
    /**
283
295
     * Returns the absolute value of this fraction.
284
296
     * @return the absolute value.
290
302
        } else {
291
303
            ret = negate();
292
304
        }
293
 
        return ret;        
 
305
        return ret;
294
306
    }
295
 
    
 
307
 
296
308
    /**
297
309
     * Compares this object to another based on size.
298
310
     * @param object the object to compare to
314
326
    public double doubleValue() {
315
327
        return (double)numerator / (double)denominator;
316
328
    }
317
 
    
 
329
 
318
330
    /**
319
331
     * Test for the equality of two fractions.  If the lowest term
320
332
     * numerator and denominators are the same for both fractions, the two
326
338
     */
327
339
    @Override
328
340
    public boolean equals(Object other) {
329
 
        boolean ret;
330
 
        
331
 
        if (this == other) { 
332
 
            ret = true;
333
 
        } else if (other == null) {
334
 
            ret = false;
335
 
        } else {
336
 
            try {
337
 
                // since fractions are always in lowest terms, numerators and
338
 
                // denominators can be compared directly for equality.
339
 
                Fraction rhs = (Fraction)other;
340
 
                ret = (numerator == rhs.numerator) &&
341
 
                    (denominator == rhs.denominator);
342
 
            } catch (ClassCastException ex) {
343
 
                // ignore exception
344
 
                ret = false;
345
 
            }
346
 
        }
347
 
        
348
 
        return ret;
 
341
        if (this == other) {
 
342
            return true;
 
343
        }
 
344
        if (other instanceof Fraction) {
 
345
            // since fractions are always in lowest terms, numerators and
 
346
            // denominators can be compared directly for equality.
 
347
            Fraction rhs = (Fraction)other;
 
348
            return (numerator == rhs.numerator) &&
 
349
                (denominator == rhs.denominator);
 
350
        }
 
351
        return false;
349
352
    }
350
 
    
 
353
 
351
354
    /**
352
355
     * Gets the fraction as a <tt>float</tt>. This calculates the fraction as
353
356
     * the numerator divided by denominator.
357
360
    public float floatValue() {
358
361
        return (float)doubleValue();
359
362
    }
360
 
    
 
363
 
361
364
    /**
362
365
     * Access the denominator.
363
366
     * @return the denominator.
365
368
    public int getDenominator() {
366
369
        return denominator;
367
370
    }
368
 
    
 
371
 
369
372
    /**
370
373
     * Access the numerator.
371
374
     * @return the numerator.
373
376
    public int getNumerator() {
374
377
        return numerator;
375
378
    }
376
 
    
 
379
 
377
380
    /**
378
381
     * Gets a hashCode for the fraction.
379
382
     * @return a hash code value for this object
380
383
     */
381
384
    @Override
382
385
    public int hashCode() {
383
 
        return 37 * (37 * 17 + getNumerator()) + getDenominator();
 
386
        return 37 * (37 * 17 + numerator) + denominator;
384
387
    }
385
 
    
 
388
 
386
389
    /**
387
390
     * Gets the fraction as an <tt>int</tt>. This returns the whole number part
388
391
     * of the fraction.
392
395
    public int intValue() {
393
396
        return (int)doubleValue();
394
397
    }
395
 
    
 
398
 
396
399
    /**
397
400
     * Gets the fraction as a <tt>long</tt>. This returns the whole number part
398
401
     * of the fraction.
402
405
    public long longValue() {
403
406
        return (long)doubleValue();
404
407
    }
405
 
    
 
408
 
406
409
    /**
407
410
     * Return the additive inverse of this fraction.
408
411
     * @return the negation of this fraction.
409
412
     */
410
413
    public Fraction negate() {
411
414
        if (numerator==Integer.MIN_VALUE) {
412
 
            throw MathRuntimeException.createArithmeticException("overflow in fraction {0}/{1}, cannot negate",
413
 
                                                                 numerator, denominator);
 
415
            throw MathRuntimeException.createArithmeticException(
 
416
                  OVERFLOW_MESSAGE, numerator, denominator);
414
417
        }
415
418
        return new Fraction(-numerator, denominator);
416
419
    }
422
425
    public Fraction reciprocal() {
423
426
        return new Fraction(denominator, numerator);
424
427
    }
425
 
    
 
428
 
426
429
    /**
427
430
     * <p>Adds the value of this fraction to another, returning the result in reduced form.
428
431
     * The algorithm follows Knuth, 4.5.1.</p>
447
450
    }
448
451
 
449
452
    /**
450
 
     * <p>Subtracts the value of another fraction from the value of this one, 
 
453
     * <p>Subtracts the value of another fraction from the value of this one,
451
454
     * returning the result in reduced form.</p>
452
455
     *
453
456
     * @param fraction  the fraction to subtract, must not be <code>null</code>
469
472
        return new Fraction(numerator - i * denominator, denominator);
470
473
    }
471
474
 
472
 
    /** 
 
475
    /**
473
476
     * Implement add and subtract using algorithm described in Knuth 4.5.1.
474
 
     * 
 
477
     *
475
478
     * @param fraction the fraction to subtract, must not be <code>null</code>
476
479
     * @param isAdd true to add, false to subtract
477
480
     * @return a <code>Fraction</code> instance with the resulting values
481
484
     */
482
485
    private Fraction addSub(Fraction fraction, boolean isAdd) {
483
486
        if (fraction == null) {
484
 
            throw MathRuntimeException.createIllegalArgumentException("null fraction");
 
487
            throw MathRuntimeException.createIllegalArgumentException(NULL_FRACTION);
485
488
        }
486
489
        // zero is identity for addition.
487
490
        if (numerator == 0) {
489
492
        }
490
493
        if (fraction.numerator == 0) {
491
494
            return this;
492
 
        }     
 
495
        }
493
496
        // if denominators are randomly distributed, d1 will be 1 about 61%
494
497
        // of the time.
495
498
        int d1 = MathUtils.gcd(denominator, fraction.denominator);
498
501
            int uvp = MathUtils.mulAndCheck(numerator, fraction.denominator);
499
502
            int upv = MathUtils.mulAndCheck(fraction.numerator, denominator);
500
503
            return new Fraction
501
 
                (isAdd ? MathUtils.addAndCheck(uvp, upv) : 
 
504
                (isAdd ? MathUtils.addAndCheck(uvp, upv) :
502
505
                 MathUtils.subAndCheck(uvp, upv),
503
506
                 MathUtils.mulAndCheck(denominator, fraction.denominator));
504
507
        }
521
524
            throw MathRuntimeException.createArithmeticException("overflow, numerator too large after multiply: {0}",
522
525
                                                                 w);
523
526
        }
524
 
        return new Fraction (w.intValue(), 
525
 
                MathUtils.mulAndCheck(denominator/d1, 
 
527
        return new Fraction (w.intValue(),
 
528
                MathUtils.mulAndCheck(denominator/d1,
526
529
                        fraction.denominator/d2));
527
530
    }
528
531
 
529
532
    /**
530
 
     * <p>Multiplies the value of this fraction by another, returning the 
 
533
     * <p>Multiplies the value of this fraction by another, returning the
531
534
     * result in reduced form.</p>
532
535
     *
533
536
     * @param fraction  the fraction to multiply by, must not be <code>null</code>
538
541
     */
539
542
    public Fraction multiply(Fraction fraction) {
540
543
        if (fraction == null) {
541
 
            throw MathRuntimeException.createIllegalArgumentException("null fraction");
 
544
            throw MathRuntimeException.createIllegalArgumentException(NULL_FRACTION);
542
545
        }
543
546
        if (numerator == 0 || fraction.numerator == 0) {
544
547
            return ZERO;
573
576
     */
574
577
    public Fraction divide(Fraction fraction) {
575
578
        if (fraction == null) {
576
 
            throw MathRuntimeException.createIllegalArgumentException("null fraction");
 
579
            throw MathRuntimeException.createIllegalArgumentException(NULL_FRACTION);
577
580
        }
578
581
        if (fraction.numerator == 0) {
579
582
            throw MathRuntimeException.createArithmeticException(
606
609
    public static Fraction getReducedFraction(int numerator, int denominator) {
607
610
        if (denominator == 0) {
608
611
            throw MathRuntimeException.createArithmeticException(
609
 
                    "zero denominator in fraction {0}/{1}",
610
 
                    numerator, denominator);
 
612
                  ZERO_DENOMINATOR_MESSAGE, numerator, denominator);
611
613
        }
612
614
        if (numerator==0) {
613
615
            return ZERO; // normalize zero.
620
622
            if (numerator==Integer.MIN_VALUE ||
621
623
                    denominator==Integer.MIN_VALUE) {
622
624
                throw MathRuntimeException.createArithmeticException(
623
 
                        "overflow in fraction {0}/{1}, cannot negate",
624
 
                        numerator, denominator);
 
625
                      OVERFLOW_MESSAGE, numerator, denominator);
625
626
            }
626
627
            numerator = -numerator;
627
628
            denominator = -denominator;
638
639
     * Returns the <code>String</code> representing this fraction, ie
639
640
     * "num / dem" or just "num" if the denominator is one.
640
641
     * </p>
641
 
     * 
 
642
     *
642
643
     * @return a string representation of the fraction.
643
644
     * @see java.lang.Object#toString()
644
645
     */