/* * Copyright (c) 2009-2015 * IT-Consulting Stephan Schloepke (http://www.schloepke.de/) * klemm software consulting Mirko Klemm (http://www.klemm-scs.com/) * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ package org.jbasics.math.arbitrary; import java.math.BigDecimal; import java.math.MathContext; public class ArbitraryRational implements ArbitraryNumber { public static final ArbitraryRational ZERO = new ArbitraryRational(ArbitraryInteger.ZERO, ArbitraryInteger.ONE); public static final ArbitraryRational ONE = new ArbitraryRational(ArbitraryInteger.ONE, ArbitraryInteger.ONE); public static final ArbitraryRational MINUS_ONE = new ArbitraryRational(ArbitraryInteger.MINUS_ONE, ArbitraryInteger.ONE); private final ArbitraryInteger numerator; private final ArbitraryInteger denominator; private ArbitraryRational(final ArbitraryInteger numerator, final ArbitraryInteger denominator) { if (denominator.isZero()) { throw new ArithmeticException("Division by zero"); } else if (denominator.isNegativ()) { this.numerator = numerator.negate(); this.denominator = denominator.abs(); } else { this.numerator = numerator; this.denominator = denominator; } } public static ArbitraryRational valueOf(final ArbitraryInteger numerator) { if (numerator.isZero()) { return ArbitraryRational.ZERO; } return new ArbitraryRational(numerator, ArbitraryInteger.ONE); } @Override public BigDecimal toNumber() { return new BigDecimal(this.numerator.toNumber()).divide(new BigDecimal(this.denominator.toNumber())); } // Converting @Override public int signum() { return this.numerator.signum(); } @Override public boolean isNegativ() { return this.numerator.isNegativ(); } @Override public boolean isPositiv() { return this.numerator.isPositiv(); } @Override public boolean isZero() { return this.numerator.isZero(); } // Checks @Override public ArbitraryRational abs() { return ArbitraryRational.valueOf(this.numerator.abs(), this.denominator); } @Override public ArbitraryRational negate() { return ArbitraryRational.valueOf(this.numerator.negate(), this.denominator); } @Override public ArbitraryRational reciprocal() { return ArbitraryRational.valueOf(this.denominator, this.numerator); } @Override public ArbitraryRational square() { return multiply(this); } @Override public ArbitraryRational increment() { return ArbitraryRational.valueOf(this.numerator.add(this.denominator), this.denominator); } @Override public ArbitraryRational decrement() { return ArbitraryRational.valueOf(this.numerator.subtract(this.denominator), this.denominator); } // Global operations @Override public ArbitraryRational add(final ArbitraryInteger summand) { return ArbitraryRational.valueOf(this.numerator.add(summand.multiply(this.denominator)), this.denominator); } @Override public ArbitraryRational subtract(final ArbitraryInteger subtrahend) { return ArbitraryRational.valueOf(this.numerator.subtract(subtrahend.multiply(this.denominator)), this.denominator); } @Override public ArbitraryRational multiply(final ArbitraryInteger factor) { return ArbitraryRational.valueOf(this.numerator.multiply(factor), this.denominator); } @Override public ArbitraryRational divide(final ArbitraryInteger divisor) { return ArbitraryRational.valueOf(this.numerator, this.denominator.multiply(divisor)); } // The integer operators @Override public ArbitraryRational add(final ArbitraryRational summand) { return ArbitraryRational.valueOf(this.numerator.multiply(summand.denominator).add(summand.numerator.multiply(this.denominator)), this.denominator.multiply(summand.denominator)); } @Override public ArbitraryRational subtract(final ArbitraryRational subtrahend) { return ArbitraryRational.valueOf(this.numerator.multiply(subtrahend.denominator).subtract(subtrahend.numerator.multiply(this.denominator)), this.denominator.multiply(subtrahend.denominator)); } @Override public ArbitraryRational multiply(final ArbitraryRational factor) { return ArbitraryRational.valueOf(this.numerator.multiply(factor.numerator), this.denominator.multiply(factor.denominator)); } @Override public ArbitraryRational divide(final ArbitraryRational divisor) { return ArbitraryRational.valueOf(this.numerator.multiply(divisor.denominator), this.denominator.multiply(divisor.numerator)); } // The rational operations public static ArbitraryRational valueOf(final ArbitraryInteger numerator, final ArbitraryInteger denominator) { if (numerator.isZero()) { return ArbitraryRational.ZERO; } return new ArbitraryRational(numerator, denominator); } public BigDecimal toNumber(final MathContext mc) { return new BigDecimal(this.numerator.toNumber()).divide(new BigDecimal(this.denominator.toNumber()), mc); } public ArbitraryInteger numerator() { return this.numerator; } public ArbitraryInteger denominator() { return this.denominator; } }