/** * Copyright 2009 Google Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package org.waveprotocol.wave.model.operation.testing; import java.math.BigInteger; public final class Rational { private static final BigInteger BI_M1 = BigInteger.valueOf(-1); public static final Rational ZERO = new Rational(0, 1); public static final Rational ONE = new Rational(1, 1); public static final Rational MINUS_ONE = new Rational(-1, 1); public static final Rational TWO = new Rational(2, 1); final BigInteger numerator; final BigInteger denominator; public Rational(int numerator, int denominator) { this(BigInteger.valueOf(numerator), BigInteger.valueOf(denominator)); } public Rational(BigInteger numerator, BigInteger denominator) { if (denominator.equals(BigInteger.ZERO)) { throw new IllegalArgumentException("Denominator must != 0"); } else if (denominator.compareTo(BigInteger.ZERO) < 0) { denominator = denominator.multiply(BI_M1); numerator = numerator.multiply(BI_M1); } // BigInteger negative = numerator.signum() < 0 ? minusOne : BigInteger.ONE; // numerator = numerator.multiply(negative); BigInteger gcd = numerator.gcd(denominator); this.numerator = numerator.divide(gcd); this.denominator = denominator.divide(gcd); } public Rational plus(Rational other) { return new Rational( numerator.multiply(other.denominator).add(other.numerator.multiply(denominator)), denominator.multiply(other.denominator)); } public Rational minus(Rational other) { return new Rational( numerator.multiply(other.denominator).add( BI_M1.multiply(other.numerator.multiply(denominator))), denominator.multiply(other.denominator)); } public Rational times(Rational other) { return new Rational( numerator.multiply(other.numerator), denominator.multiply(other.denominator)); } public Rational dividedBy(Rational other) { if (other.numerator.equals(BigInteger.ZERO)) { throw new IllegalArgumentException("Division by zero"); } return times(other.reciprocal()); } public Rational reciprocal() { if (numerator.equals(BigInteger.ZERO)) { throw new IllegalArgumentException("Division by zero"); } return new Rational(denominator, numerator); } @Override public String toString() { return numerator + (denominator.equals(BigInteger.ONE) || denominator.equals(BigInteger.ZERO) ? "" : "/" + denominator); } // eclipse generated @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((denominator == null) ? 0 : denominator.hashCode()); result = prime * result + ((numerator == null) ? 0 : numerator.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Rational other = (Rational) obj; if (denominator == null) { if (other.denominator != null) return false; } else if (!denominator.equals(other.denominator)) return false; if (numerator == null) { if (other.numerator != null) return false; } else if (!numerator.equals(other.numerator)) return false; return true; } }