All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.decimal4j.immutable.Decimal5f Maven / Gradle / Ivy

Go to download

Java library for fast fixed-point arithmetic based on longs with support for up to 18 decimal places.

The newest version!
/**
 * The MIT License (MIT)
 *
 * Copyright (c) 2015-2016 decimal4j (tools4j), Marco Terzer
 *
 * 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.decimal4j.immutable;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.math.RoundingMode;

import org.decimal4j.api.Decimal;
import org.decimal4j.api.DecimalArithmetic;
import org.decimal4j.base.AbstractImmutableDecimal;
import org.decimal4j.exact.Multipliable5f;
import org.decimal4j.factory.Factory5f;
import org.decimal4j.mutable.MutableDecimal5f;
import org.decimal4j.scale.Scale5f;

/**
 * Decimal5f represents an immutable decimal number with a fixed
 * number of 5 digits to the right of the decimal point.
 * 

* All methods for this class throw {@code NullPointerException} when passed a * {@code null} object reference for any input parameter. */ public final class Decimal5f extends AbstractImmutableDecimal { private static final long serialVersionUID = 1L; /** Scale value 5 for {@code Decimal5f} returned by {@link #getScale()}.*/ public static final int SCALE = 5; /** Scale metrics constant for {@code Decimal5f} returned by {@link #getScaleMetrics()}.*/ public static final Scale5f METRICS = Scale5f.INSTANCE; /** Factory constant for {@code Decimal5f} returned by {@link #getFactory()}.*/ public static final Factory5f FACTORY = Factory5f.INSTANCE; /** * Default arithmetic for {@code Decimal5f} performing unchecked operations with rounding mode * {@link RoundingMode#HALF_UP HALF_UP}. */ public static final DecimalArithmetic DEFAULT_ARITHMETIC = METRICS.getDefaultArithmetic(); /** * Default arithmetic for {@code Decimal5f} performing checked operations with rounding mode * {@link RoundingMode#HALF_UP HALF_UP}. */ public static final DecimalArithmetic DEFAULT_CHECKED_ARITHMETIC = METRICS.getDefaultCheckedArithmetic(); /** The unscaled long value that represents one.*/ public static final long ONE_UNSCALED = METRICS.getScaleFactor(); /** The {@code Decimal5f} constant zero.*/ public static final Decimal5f ZERO = new Decimal5f(0); /** * A constant holding the smallest positive value a {@code Decimal5f} * can have, 10-5. */ public static final Decimal5f ULP = new Decimal5f(1); /** * Initialize static constant array when class is loaded. */ private static final int MAX_CONSTANT = 10; private static final Decimal5f POS_CONST[] = new Decimal5f[MAX_CONSTANT+1]; private static final Decimal5f NEG_CONST[] = new Decimal5f[MAX_CONSTANT+1]; static { for (int i = 1; i <= MAX_CONSTANT; i++) { POS_CONST[i] = new Decimal5f(ONE_UNSCALED * i); NEG_CONST[i] = new Decimal5f(-ONE_UNSCALED * i); } } /** The {@code Decimal5f} constant 1.*/ public static final Decimal5f ONE = valueOf(1); /** The {@code Decimal5f} constant 2.*/ public static final Decimal5f TWO = valueOf(2); /** The {@code Decimal5f} constant 3.*/ public static final Decimal5f THREE = valueOf(3); /** The {@code Decimal5f} constant 4.*/ public static final Decimal5f FOUR = valueOf(4); /** The {@code Decimal5f} constant 5.*/ public static final Decimal5f FIVE = valueOf(5); /** The {@code Decimal5f} constant 6.*/ public static final Decimal5f SIX = valueOf(6); /** The {@code Decimal5f} constant 7.*/ public static final Decimal5f SEVEN = valueOf(7); /** The {@code Decimal5f} constant 8.*/ public static final Decimal5f EIGHT = valueOf(8); /** The {@code Decimal5f} constant 9.*/ public static final Decimal5f NINE = valueOf(9); /** The {@code Decimal5f} constant 10.*/ public static final Decimal5f TEN = valueOf(10); /** The {@code Decimal5f} constant 100.*/ public static final Decimal5f HUNDRED = new Decimal5f(100 * ONE_UNSCALED); /** The {@code Decimal5f} constant 1000.*/ public static final Decimal5f THOUSAND = new Decimal5f(1000 * ONE_UNSCALED); /** The {@code Decimal5f} constant 106.*/ public static final Decimal5f MILLION = new Decimal5f(1000000 * ONE_UNSCALED); /** The {@code Decimal5f} constant 109.*/ public static final Decimal5f BILLION = new Decimal5f(1000000000 * ONE_UNSCALED); /** The {@code Decimal5f} constant 1012.*/ public static final Decimal5f TRILLION = new Decimal5f(1000000000000L * ONE_UNSCALED); /** The {@code Decimal5f} constant -1.*/ public static final Decimal5f MINUS_ONE = valueOf(-1); /** The {@code Decimal5f} constant 0.5.*/ public static final Decimal5f HALF = new Decimal5f(ONE_UNSCALED / 2); /** The {@code Decimal5f} constant 0.1.*/ public static final Decimal5f TENTH = new Decimal5f(ONE_UNSCALED / 10); /** The {@code Decimal5f} constant 0.01.*/ public static final Decimal5f HUNDREDTH = new Decimal5f(ONE_UNSCALED / 100); /** The {@code Decimal5f} constant 0.001.*/ public static final Decimal5f THOUSANDTH = new Decimal5f(ONE_UNSCALED / 1000); /** * A constant holding the maximum value a {@code Decimal5f} can have, * 92233720368547.75807. */ public static final Decimal5f MAX_VALUE = new Decimal5f(Long.MAX_VALUE); /** * A constant holding the maximum integer value a {@code Decimal5f} * can have, 92233720368547.00000. */ public static final Decimal5f MAX_INTEGER_VALUE = new Decimal5f((Long.MAX_VALUE / ONE_UNSCALED) * ONE_UNSCALED); /** * A constant holding the minimum value a {@code Decimal5f} can have, * -92233720368547.75808. */ public static final Decimal5f MIN_VALUE = new Decimal5f(Long.MIN_VALUE); /** * A constant holding the minimum integer value a {@code Decimal5f} * can have, -92233720368547.00000. */ public static final Decimal5f MIN_INTEGER_VALUE = new Decimal5f((Long.MIN_VALUE / ONE_UNSCALED) * ONE_UNSCALED); /** * Private constructor with unscaled value. * * @param unscaled the unscaled value */ private Decimal5f(long unscaled) { super(unscaled); } /** * Translates the string representation of a {@code Decimal} into a * {@code Decimal5f}. The string representation consists of an * optional sign, {@code '+'} or {@code '-'} , followed by a sequence of * zero or more decimal digits ("the integer"), optionally followed by a * fraction. *

* The fraction consists of a decimal point followed by zero or more decimal * digits. The string must contain at least one digit in either the integer * or the fraction. If the fraction contains more than 5 digits, the * value is rounded using {@link RoundingMode#HALF_UP HALF_UP} rounding. An * exception is thrown if the value is too large to be represented as a * {@code Decimal5f}. * * @param value * String value to convert into a {@code Decimal5f} * @throws NumberFormatException * if {@code value} does not represent a valid {@code Decimal} * or if the value is too large to be represented as a * {@code Decimal5f} */ public Decimal5f(String value) { super(DEFAULT_CHECKED_ARITHMETIC.parse(value)); } @Override public final Scale5f getScaleMetrics() { return METRICS; } @Override public final int getScale() { return SCALE; } @Override public final Factory5f getFactory() { return FACTORY; } @Override protected final Decimal5f self() { return this; } @Override protected final DecimalArithmetic getDefaultArithmetic() { return DEFAULT_ARITHMETIC; } @Override protected final DecimalArithmetic getDefaultCheckedArithmetic() { return DEFAULT_CHECKED_ARITHMETIC; } @Override protected final DecimalArithmetic getRoundingDownArithmetic() { return METRICS.getRoundingDownArithmetic(); } @Override protected final DecimalArithmetic getRoundingFloorArithmetic() { return METRICS.getRoundingFloorArithmetic(); } @Override protected final DecimalArithmetic getRoundingHalfEvenArithmetic() { return METRICS.getRoundingHalfEvenArithmetic(); } @Override protected final DecimalArithmetic getRoundingUnnecessaryArithmetic() { return METRICS.getRoundingUnnecessaryArithmetic(); } /** * Returns a {@code Decimal5f} whose value is numerically equal to * that of the specified {@code long} value. An exception is thrown if the * specified value is too large to be represented as a {@code Decimal5f}. * * @param value * long value to convert into a {@code Decimal5f} * @return a {@code Decimal5f} value numerically equal to the specified * {@code long} value * @throws IllegalArgumentException * if {@code value} is too large to be represented as a * {@code Decimal5f} */ public static Decimal5f valueOf(long value) { if (value == 0) return ZERO; if (value > 0 & value <= MAX_CONSTANT) return POS_CONST[(int) value]; else if (value < 0 & value >= -MAX_CONSTANT) return NEG_CONST[(int) -value]; return valueOfUnscaled(DEFAULT_CHECKED_ARITHMETIC.fromLong(value)); } /** * Returns a {@code Decimal5f} whose value is calculated by * rounding the specified {@code float} argument to scale 5 * using {@link RoundingMode#HALF_UP HALF_UP} rounding. An exception is thrown * if the specified value is too large to be represented as a {@code Decimal5f}. * * @param value * float value to convert into a {@code Decimal5f} * @return a {@code Decimal5f} calculated as: roundHALF_UP(value) * @throws IllegalArgumentException * if {@code value} is NaN or infinite or if the magnitude is * too large for the float to be represented as a {@code Decimal5f} */ public static Decimal5f valueOf(float value) { return valueOfUnscaled(DEFAULT_CHECKED_ARITHMETIC.fromFloat(value)); } /** * Returns a {@code Decimal5f} whose value is calculated by * rounding the specified {@code float} argument to scale 5 * using the specified {@code roundingMode}. An exception is thrown * if the specified value is too large to be represented as a {@code Decimal5f}. * * @param value * float value to convert into a {@code Decimal5f} * @param roundingMode * the rounding mode to apply during the conversion if necessary * @return a {@code Decimal5f} calculated as: round(value) * @throws IllegalArgumentException * if {@code value} is NaN or infinite or if the magnitude is * too large for the float to be represented as a {@code Decimal5f} * @throws ArithmeticException * if {@code roundingMode==UNNECESSARY} and rounding is * necessary */ public static Decimal5f valueOf(float value, RoundingMode roundingMode) { return valueOfUnscaled(METRICS.getCheckedArithmetic(roundingMode).fromFloat(value)); } /** * Returns a {@code Decimal5f} whose value is calculated by * rounding the specified {@code double} argument to scale 5 * using {@link RoundingMode#HALF_UP HALF_UP} rounding. An exception is thrown * if the specified value is too large to be represented as a {@code Decimal5f}. * * @param value * double value to convert into a {@code Decimal5f} * @return a {@code Decimal5f} calculated as: roundHALF_UP(value) * @throws IllegalArgumentException * if {@code value} is NaN or infinite or if the magnitude is * too large for the double to be represented as a {@code Decimal5f} */ public static Decimal5f valueOf(double value) { return valueOfUnscaled(DEFAULT_CHECKED_ARITHMETIC.fromDouble(value)); } /** * Returns a {@code Decimal5f} whose value is calculated by * rounding the specified {@code double} argument to scale 5 * using the specified {@code roundingMode}. An exception is thrown * if the specified value is too large to be represented as a {@code Decimal5f}. * * @param value * double value to convert into a {@code Decimal5f} * @param roundingMode * the rounding mode to apply during the conversion if necessary * @return a {@code Decimal5f} calculated as: round(value) * @throws IllegalArgumentException * if {@code value} is NaN or infinite or if the magnitude is * too large for the double to be represented as a {@code Decimal5f} * @throws ArithmeticException * if {@code roundingMode==UNNECESSARY} and rounding is * necessary */ public static Decimal5f valueOf(double value, RoundingMode roundingMode) { return valueOfUnscaled(METRICS.getCheckedArithmetic(roundingMode).fromDouble(value)); } /** * Returns a {@code Decimal5f} whose value is numerically equal to that of * the specified {@link BigInteger} value. An exception is thrown if the * specified value is too large to be represented as a {@code Decimal5f}. * * @param value * {@code BigInteger} value to convert into a {@code Decimal5f} * @return a {@code Decimal5f} value numerically equal to the specified big * integer value * @throws IllegalArgumentException * if {@code value} is too large to be represented as a {@code Decimal5f} */ public static Decimal5f valueOf(BigInteger value) { return valueOfUnscaled(DEFAULT_CHECKED_ARITHMETIC.fromBigInteger(value)); } /** * Returns a {@code Decimal5f} whose value is calculated by rounding * the specified {@link BigDecimal} argument to scale 5 using * {@link RoundingMode#HALF_UP HALF_UP} rounding. An exception is thrown if the * specified value is too large to be represented as a {@code Decimal5f}. * * @param value * {@code BigDecimal} value to convert into a {@code Decimal5f} * @return a {@code Decimal5f} calculated as: roundHALF_UP(value) * @throws IllegalArgumentException * if {@code value} is too large to be represented as a {@code Decimal5f} */ public static Decimal5f valueOf(BigDecimal value) { return valueOfUnscaled(DEFAULT_CHECKED_ARITHMETIC.fromBigDecimal(value)); } /** * Returns a {@code Decimal5f} whose value is calculated by rounding * the specified {@link BigDecimal} argument to scale 5 using * the specified {@code roundingMode}. An exception is thrown if the * specified value is too large to be represented as a {@code Decimal5f}. * * @param value * {@code BigDecimal} value to convert into a {@code Decimal5f} * @param roundingMode * the rounding mode to apply during the conversion if necessary * @return a {@code Decimal5f} calculated as: round(value) * @throws IllegalArgumentException * if {@code value} is too large to be represented as a {@code Decimal5f} * @throws ArithmeticException * if {@code roundingMode==UNNECESSARY} and rounding is * necessary */ public static Decimal5f valueOf(BigDecimal value, RoundingMode roundingMode) { return valueOfUnscaled(METRICS.getCheckedArithmetic(roundingMode).fromBigDecimal(value)); } /** * Returns a {@code Decimal5f} whose value is calculated by rounding * the specified {@link Decimal} argument to scale 5 using * {@link RoundingMode#HALF_UP HALF_UP} rounding. An exception is thrown if the * specified value is too large to be represented as a {@code Decimal5f}. * * @param value * Decimal value to convert into a {@code Decimal5f} * @return a {@code Decimal5f} calculated as: roundHALF_UP(value) * @throws IllegalArgumentException * if {@code value} is too large to be represented as a {@code Decimal5f} */ public static Decimal5f valueOf(Decimal value) { if (value instanceof Decimal5f) { return (Decimal5f)value; } return valueOfUnscaled(value.unscaledValue(), value.getScale()); } /** * Returns a {@code Decimal5f} whose value is calculated by rounding * the specified {@link Decimal} argument to scale 5 using * the specified {@code roundingMode}. An exception is thrown if the * specified value is too large to be represented as a {@code Decimal5f}. * * @param value * Decimal value to convert into a {@code Decimal5f} * @param roundingMode * the rounding mode to apply during the conversion if necessary * @return a {@code Decimal5f} calculated as: round(value) * @throws IllegalArgumentException * if {@code value} is too large to be represented as a {@code Decimal5f} * @throws ArithmeticException * if {@code roundingMode==UNNECESSARY} and rounding is * necessary */ public static Decimal5f valueOf(Decimal value, RoundingMode roundingMode) { if (value instanceof Decimal5f) { return (Decimal5f)value; } return valueOfUnscaled(value.unscaledValue(), value.getScale(), roundingMode); } /** * Translates the string representation of a {@code Decimal} into a * {@code Decimal5f}. The string representation consists of an * optional sign, {@code '+'} or {@code '-'} , followed by a sequence of * zero or more decimal digits ("the integer"), optionally followed by a * fraction. *

* The fraction consists of a decimal point followed by zero or more decimal * digits. The string must contain at least one digit in either the integer * or the fraction. If the fraction contains more than 5 digits, the * value is rounded using {@link RoundingMode#HALF_UP HALF_UP} rounding. An * exception is thrown if the value is too large to be represented as a * {@code Decimal5f}. * * @param value * String value to convert into a {@code Decimal5f} * @return a {@code Decimal5f} calculated as: roundHALF_UP(value) * @throws NumberFormatException * if {@code value} does not represent a valid {@code Decimal} * or if the value is too large to be represented as a * {@code Decimal5f} */ public static Decimal5f valueOf(String value) { return valueOfUnscaled(DEFAULT_CHECKED_ARITHMETIC.parse(value)); } /** * Translates the string representation of a {@code Decimal} into a * {@code Decimal5f}. The string representation consists of an * optional sign, {@code '+'} or {@code '-'} , followed by a sequence of * zero or more decimal digits ("the integer"), optionally followed by a * fraction. *

* The fraction consists of a decimal point followed by zero or more decimal * digits. The string must contain at least one digit in either the integer * or the fraction. If the fraction contains more than 5 digits, the * value is rounded using the specified {@code roundingMode}. An exception * is thrown if the value is too large to be represented as a {@code Decimal5f}. * * @param value * String value to convert into a {@code Decimal5f} * @param roundingMode * the rounding mode to apply if the fraction contains more than * 5 digits * @return a {@code Decimal5f} calculated as: round(value) * @throws NumberFormatException * if {@code value} does not represent a valid {@code Decimal} * or if the value is too large to be represented as a * {@code Decimal5f} * @throws ArithmeticException * if {@code roundingMode==UNNECESSARY} and rounding is * necessary */ public static Decimal5f valueOf(String value, RoundingMode roundingMode) { return valueOfUnscaled(METRICS.getCheckedArithmetic(roundingMode).parse(value)); } /** * Returns a {@code Decimal5f} whose value is numerically equal to * (unscaledValue × 10-5). * * @param unscaledValue * unscaled value to convert into a {@code Decimal5f} * @return a {@code Decimal5f} calculated as: * unscaledValue × 10-5 */ public static Decimal5f valueOfUnscaled(long unscaledValue) { if (unscaledValue == 0) { return ZERO; } if (unscaledValue == 1) { return ULP; } if (unscaledValue == ONE_UNSCALED) { return ONE; } if (unscaledValue == -ONE_UNSCALED) { return MINUS_ONE; } return new Decimal5f(unscaledValue); } /** * Returns a {@code Decimal5f} whose value is numerically equal to * (unscaledValue × 10-scale). The result is * rounded to scale 5 using {@link RoundingMode#HALF_UP HALF_UP} * rounding. An exception is thrown if the specified value is too large * to be represented as a {@code Decimal5f}. * * @param unscaledValue * unscaled value to convert into a {@code Decimal5f} * @param scale * the scale to apply to {@code unscaledValue} * @return a {@code Decimal5f} calculated as: * roundHALF_UP(unscaledValue × 10-scale) * @throws IllegalArgumentException * if the specified value is too large to be represented as a * {@code Decimal5f} */ public static Decimal5f valueOfUnscaled(long unscaledValue, int scale) { return valueOfUnscaled(DEFAULT_CHECKED_ARITHMETIC.fromUnscaled(unscaledValue, scale)); } /** * Returns a {@code Decimal5f} whose value is numerically equal to * (unscaledValue × 10-scale). The result * is rounded to scale 5 using the specified {@code roundingMode}. * An exception is thrown if the specified value is too large to be * represented as a {@code Decimal5f}. * * @param unscaledValue * unscaled value to convert into a Decimal5 * @param scale * the scale to apply to {@code unscaledValue} * @param roundingMode * the rounding mode to apply during the conversion if necessary * @return a {@code Decimal5f} calculated as: * round(unscaledValue × 10-scale) * @throws IllegalArgumentException * if the specified value is too large to be represented as a {@code Decimal5f} */ public static Decimal5f valueOfUnscaled(long unscaledValue, int scale, RoundingMode roundingMode) { return valueOfUnscaled(METRICS.getCheckedArithmetic(roundingMode).fromUnscaled(unscaledValue, scale)); } @Override protected Decimal5f createOrAssign(long unscaled) { return valueOfUnscaled(unscaled); } @Override protected Decimal5f create(long unscaled) { return valueOfUnscaled(unscaled); } @Override protected Decimal5f[] createArray(int length) { return new Decimal5f[length]; } /** * Returns this {@code Decimal} as a multipliable factor for typed * exact multiplication. The second factor is passed to one of the * {@code by(..)} methods of the returned multiplier. The scale of * the result is the sum of the scales of {@code this} Decimal and the * second factor passed to the {@code by(..)} method. *

* The method is similar to {@link #multiplyExact(Decimal) multiplyExact(Decimal)} but the result * is retrieved in exact typed form with the correct result scale. *

* For instance one can write: *

	 * Decimal7f product = this.multiplyExact().by(Decimal2f.FIVE);
	 * 
* * @return a multipliable object encapsulating this Decimal as first factor * of an exact multiplication */ public Multipliable5f multiplyExact() { return new Multipliable5f(this); } @Override public MutableDecimal5f toMutableDecimal() { return new MutableDecimal5f(this); } @Override public Decimal5f toImmutableDecimal() { return this; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy