/**
* Copyright (C) 2019 Adrien Hopkins
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see
* Two units can be divided if they are part of the same unit system. If {@code divisor} does not meet this * condition, an {@code IllegalArgumentException} should be thrown. *
* * @param divisor * unit to divide by * @return quotient of two units * @throws IllegalArgumentException * if {@code divisor} is not compatible for division as described above * @throws NullPointerException * if {@code divisor} is null * @since 2018-12-22 * @since v0.1.0 */ public LinearUnit dividedBy(final LinearUnit divisor) { Objects.requireNonNull(divisor, "other must not be null"); // check that these units can be multiplied if (!this.getSystem().equals(divisor.getSystem())) throw new IllegalArgumentException( String.format("Incompatible units for division \"%s\" and \"%s\".", this, divisor)); // divide the units final BaseUnit base = this.getBase().dividedBy(divisor.getBase()); return new LinearUnit(base, this.getConversionFactor() / divisor.getConversionFactor()); } @Override public boolean equals(final Object obj) { if (!(obj instanceof LinearUnit)) return false; final LinearUnit other = (LinearUnit) obj; return Objects.equals(this.getSystem(), other.getSystem()) && Objects.equals(this.getDimension(), other.getDimension()) && DecimalComparison.equals(this.getConversionFactor(), other.getConversionFactor()); } /** * @return conversion factor between this unit and its base * @since 2018-12-22 * @since v0.1.0 */ public final double getConversionFactor() { return this.conversionFactor; } @Override public int hashCode() { final int prime = 31; int result = 1; result = result * prime + this.getSystem().hashCode(); result = result * prime + this.getDimension().hashCode(); result = result * prime + Double.hashCode(this.getConversionFactor()); return result; } /** * Returns the difference of this unit and another. ** Two units can be subtracted if they have the same base. If {@code subtrahend} does not meet this condition, an * {@code IllegalArgumentException} will be thrown. *
* * @param subtrahend * unit to subtract * @return difference of units * @throws IllegalArgumentException * if {@code subtrahend} is not compatible for subtraction as described above * @throws NullPointerException * if {@code subtrahend} is null * @since 2019-03-17 */ public LinearUnit minus(final LinearUnit subtrahendend) { Objects.requireNonNull(subtrahendend, "addend must not be null."); // reject subtrahends that cannot be added to this unit if (!this.getBase().equals(subtrahendend.getBase())) throw new IllegalArgumentException( String.format("Incompatible units for subtraction \"%s\" and \"%s\".", this, subtrahendend)); // add the units return new LinearUnit(this.getBase(), this.getConversionFactor() - subtrahendend.getConversionFactor()); } /** * Returns the sum of this unit and another. ** Two units can be added if they have the same base. If {@code addend} does not meet this condition, an * {@code IllegalArgumentException} will be thrown. *
* * @param addend * unit to add * @return sum of units * @throws IllegalArgumentException * if {@code addend} is not compatible for addition as described above * @throws NullPointerException * if {@code addend} is null * @since 2019-03-17 */ public LinearUnit plus(final LinearUnit addend) { Objects.requireNonNull(addend, "addend must not be null."); // reject addends that cannot be added to this unit if (!this.getBase().equals(addend.getBase())) throw new IllegalArgumentException( String.format("Incompatible units for addition \"%s\" and \"%s\".", this, addend)); // add the units return new LinearUnit(this.getBase(), this.getConversionFactor() + addend.getConversionFactor()); } /** * Multiplies this unit by a scalar. * * @param multiplier * scalar to multiply by * @return product * @since 2018-12-23 * @since v0.1.0 */ public LinearUnit times(final double multiplier) { return new LinearUnit(this.getBase(), this.getConversionFactor() * multiplier); } /** * Returns the product of this unit and another. ** Two units can be multiplied if they are part of the same unit system. If {@code multiplier} does not meet this * condition, an {@code IllegalArgumentException} should be thrown. *
* * @param multiplier * unit to multiply by * @return product of two units * @throws IllegalArgumentException * if {@code multiplier} is not compatible for multiplication as described above * @throws NullPointerException * if {@code multiplier} is null * @since 2018-12-22 * @since v0.1.0 */ public LinearUnit times(final LinearUnit multiplier) { Objects.requireNonNull(multiplier, "other must not be null"); // check that these units can be multiplied if (!this.getSystem().equals(multiplier.getSystem())) throw new IllegalArgumentException( String.format("Incompatible units for multiplication \"%s\" and \"%s\".", this, multiplier)); // multiply the units final BaseUnit base = this.getBase().times(multiplier.getBase()); return new LinearUnit(base, this.getConversionFactor() * multiplier.getConversionFactor()); } /** * Returns this unit but to an exponent. * * @param exponent * exponent to exponientate unit to * @return exponientated unit * @since 2019-01-15 * @since v0.1.0 */ public LinearUnit toExponent(final int exponent) { return new LinearUnit(this.getBase().toExponent(exponent), Math.pow(this.conversionFactor, exponent)); } @Override public String toString() { return super.toString() + String.format(" (equal to %s * base)", this.getConversionFactor()); } /** * Returns the result of applying {@code prefix} to this unit. * * @param prefix * prefix to apply * @return unit with prefix * @since 2019-03-18 */ public LinearUnit withPrefix(final UnitPrefix prefix) { return this.times(prefix.getMultiplier()); } }