Class Decimal

  • All Implemented Interfaces:
    Serializable, Comparable<Decimal>

    public final class Decimal
    extends Object
    implements Serializable, Comparable<Decimal>
    A decimal number, similar to BigDecimal, but optimized for the needs of finance.

    This class represents a decimal number using a long unscaled value and an int scale. The scale is constrained to be from 0 to 18. The unscaled value limits the precision to 18 digits. Given this, the class supports 18 decimal places for values between -1 and 1, 17 decimal places for values between -10 and 10, and so on. Fractional values never have trailing zeros, thus the comparator is compatible with equals.

    See Also:
    Serialized Form
    • Field Detail

      • ZERO

        public static final Decimal ZERO
        A decimal value representing zero.
      • MAX_VALUE

        public static final Decimal MAX_VALUE
        A decimal value representing the largest supported value.
      • MIN_VALUE

        public static final Decimal MIN_VALUE
        A decimal value representing the smallest supported value.
    • Method Detail

      • of

        public static Decimal of​(long value)
        Obtains an instance from a long.
        Parameters:
        value - the value
        Returns:
        the equivalent decimal
      • of

        public static Decimal of​(double value)
        Obtains an instance from a double.

        This operates as though the double is converted to a String and then parsed using of(String).

        Parameters:
        value - the value
        Returns:
        the equivalent decimal
        Throws:
        IllegalArgumentException - if the value is not finite or is too large
      • of

        public static Decimal of​(BigDecimal value)
        Obtains an instance from a BigDecimal.

        The scale is adjusted to be in the range 0-18, with any smaller fractional part dropped by truncation.

        Parameters:
        value - the value
        Returns:
        the equivalent decimal
        Throws:
        IllegalArgumentException - if the value is too large
      • ofScaled

        public static Decimal ofScaled​(long unscaled,
                                       int scale)
        Obtains an instance from an unscaled value and a scale.

        The scale is adjusted to be in the range 0-18, with any smaller fractional part dropped by truncation. The result is normalized to have no fractional trailing zeroes.

        For example, Decimal.ofScaled(1230, 2) returns a decimal with the value '12.3'.

        Parameters:
        unscaled - the unscaled value
        scale - the scale
        Returns:
        the equivalent decimal
        Throws:
        IllegalArgumentException - if the value is too large
      • unscaledValue

        public long unscaledValue()
        Returns the unscaled part of the value.
        Returns:
        the unscaled value
      • scale

        public int scale()
        Returns the scale.
        Returns:
        the scale, from 0 to 18
      • plus

        public Decimal plus​(Decimal other)
        Returns a decimal value that is equal to this value plus the specified value.

        The result will have a scale in the range 0-18. The result may be truncated (rounded down) if necessary.

        Parameters:
        other - the other decimal
        Returns:
        the result of the addition
        Throws:
        IllegalArgumentException - if the result is too large
      • plus

        public Decimal plus​(long other)
        Returns a decimal value that is equal to this value plus the specified value.

        The result will have a scale in the range 0-18. The result may be truncated (rounded down) if necessary.

        Parameters:
        other - the other decimal
        Returns:
        the result of the addition
        Throws:
        IllegalArgumentException - if the result is too large
      • plus

        public Decimal plus​(double other)
        Returns a decimal value that is equal to this value plus the specified value.

        The double is converted to a Decimal before the calculation. The result will have a scale in the range 0-18. The result may be truncated (rounded down) if necessary.

        Parameters:
        other - the other decimal
        Returns:
        the result of the addition
        Throws:
        IllegalArgumentException - if the result is too large
      • minus

        public Decimal minus​(Decimal other)
        Returns a decimal value that is equal to this value minus the specified value.

        The result will have a scale in the range 0-18. The result may be truncated (rounded down) if necessary.

        Parameters:
        other - the other decimal
        Returns:
        the result of the subtraction
        Throws:
        IllegalArgumentException - if the result is too large
      • minus

        public Decimal minus​(long other)
        Returns a decimal value that is equal to this value minus the specified value.

        The result will have a scale in the range 0-18. The result may be truncated (rounded down) if necessary.

        Parameters:
        other - the other value
        Returns:
        the result of the subtraction
        Throws:
        IllegalArgumentException - if the result is too large
      • minus

        public Decimal minus​(double other)
        Returns a decimal value that is equal to this value minus the specified value.

        The double is converted to a Decimal before the calculation. The result will have a scale in the range 0-18. The result may be truncated (rounded down) if necessary.

        Parameters:
        other - the other value
        Returns:
        the result of the subtraction
        Throws:
        IllegalArgumentException - if the result is too large
      • multipliedBy

        public Decimal multipliedBy​(Decimal other)
        Returns a decimal value that is equal to this value multiplied by the specified value.

        The result will have a scale in the range 0-18.

        Parameters:
        other - the other value
        Returns:
        the result of the multiplication
        Throws:
        IllegalArgumentException - if the result is too large
      • multipliedBy

        public Decimal multipliedBy​(long other)
        Returns a decimal value that is equal to this value multiplied by the specified value.

        The result will have a scale in the range 0-18.

        Parameters:
        other - the other value
        Returns:
        the result of the multiplication
        Throws:
        IllegalArgumentException - if the result is too large
      • multipliedBy

        public Decimal multipliedBy​(double other)
        Returns a decimal value that is equal to this value multiplied by the specified value.

        The double is converted to a Decimal before the calculation. The result will have a scale in the range 0-18.

        Parameters:
        other - the other value
        Returns:
        the result of the multiplication
        Throws:
        IllegalArgumentException - if the result is too large
      • movePoint

        public Decimal movePoint​(int movement)
        Returns a decimal value with the decimal point moved.

        This can be used to multiply or divide by powers of ten. Positive values move right (multiply), negative values move left (divide)

        Decimal.of(1.235d).movePoint(2) returns a decimal with the value '123.5'.

        Decimal.of(1.235d).movePoint(-2) returns a decimal with the value '0.01235'.

        Parameters:
        movement - the amount to move by, positive to move right (multiply), negative to move left (divide)
        Returns:
        the result of the movement
        Throws:
        IllegalArgumentException - if the result is too large
      • dividedBy

        public Decimal dividedBy​(Decimal other)
        Returns a decimal value that is equal to this value divided by the specified value.

        The result will have a scale in the range 0-18. The result may be truncated (rounded down) if necessary.

        Parameters:
        other - the other value
        Returns:
        the result of the division
        Throws:
        ArithmeticException - if dividing by zero
        IllegalArgumentException - if the result is too large
      • dividedBy

        public Decimal dividedBy​(Decimal other,
                                 RoundingMode roundingMode)
        Returns a decimal value that is equal to this value divided by the specified value, with a rounding mode.

        The result will have a scale in the range 0-18.

        Parameters:
        other - the other value
        roundingMode - the rounding mode
        Returns:
        the result of the division
        Throws:
        ArithmeticException - if dividing by zero
        IllegalArgumentException - if the result is too large
      • dividedBy

        public Decimal dividedBy​(long other)
        Returns a decimal value that is equal to this value divided by the specified value.

        The result will have a scale in the range 0-18. The result may be truncated (rounded down) if necessary.

        Parameters:
        other - the other value
        Returns:
        the result of the division
        Throws:
        ArithmeticException - if dividing by zero
        IllegalArgumentException - if the result is too large
      • dividedBy

        public Decimal dividedBy​(double other)
        Returns a decimal value that is equal to this value divided by the specified value.

        The double is converted to a Decimal before the calculation. The result will have a scale in the range 0-18. The result may be truncated (rounded down) if necessary.

        Parameters:
        other - the other value
        Returns:
        the result of the multiplication
        Throws:
        IllegalArgumentException - if the result is too large
      • roundToScale

        public Decimal roundToScale​(int desiredScale,
                                    RoundingMode roundingMode)
        Returns a decimal value rounded to the specified scale.

        This ensures that the result has the specified scale or less, because trailing zeroes are removed. Specifying a scale of 18 or greater will have no effect. The result will have a scale in the range 0-18.

        Decimal.of(1.235d).roundToScale(2, HALF_UP) returns a decimal with the value '1.24'.

        Decimal.of(1.201d).roundToScale(2, HALF_UP) returns a decimal with the value '1.2'.

        Decimal.of(1235).roundToScale(-1, HALF_UP) returns a decimal with the value '1240'.

        Parameters:
        desiredScale - the scale, positive for decimal places, negative to round the integer-part
        roundingMode - the rounding mode
        Returns:
        the result of the round
        Throws:
        IllegalArgumentException - if the scale is -18 or less
      • roundToPrecision

        public Decimal roundToPrecision​(int precision,
                                        RoundingMode roundingMode)
        Returns a decimal value rounded to the specified precision.

        This ensures that the result has no more than the specified precision. Specifying a precision of 18 or greater will have no effect. The result will have a scale in the range 0-18.

        Note that the decimal 12,000 is considered to have a precision of 2 and scale -3 for the purpose of rounding. In the result it will however be stored with a scale of 0, which could be viewed as a precision of 5.

        Parameters:
        precision - the precision, not negative
        roundingMode - the rounding mode
        Returns:
        the result of the round
      • isZero

        public boolean isZero()
        Checks if the decimal is zero.
        Returns:
        true if zero
      • abs

        public Decimal abs()
        Returns a decimal value that is positive.
        Returns:
        the positive absolute value
      • negated

        public Decimal negated()
        Returns a decimal value that is negated.
        Returns:
        the negated value
      • mapAsDouble

        public Decimal mapAsDouble​(DoubleUnaryOperator fn)
        Maps this decimal value using the maths operations of double.

        Note that double maths operations can be imprecise.

        Parameters:
        fn - the function to apply
        Returns:
        the result of the function
        Throws:
        IllegalArgumentException - if the result is too large
      • mapAsBigDecimal

        public Decimal mapAsBigDecimal​(UnaryOperator<BigDecimal> fn)
        Maps this decimal value using the maths operations of BigDecimal.
        Parameters:
        fn - the function to apply
        Returns:
        the result of the function
        Throws:
        IllegalArgumentException - if the result is too large
      • doubleValue

        public double doubleValue()
        Returns the equivalent double.
        Returns:
        the equivalent value
      • longValue

        public long longValue()
        Returns the equivalent long.

        This truncates any fractional part.

        Returns:
        the equivalent value
      • toBigDecimal

        public BigDecimal toBigDecimal()
        Returns the equivalent BigDecimal.
        Returns:
        the equivalent value
      • toFixedScale

        public FixedScaleDecimal toFixedScale​(int fixedScale)
        Returns the equivalent FixedScaleDecimal.

        Callers should call roundToScale(int, RoundingMode) first if scale is unknown.

        Parameters:
        fixedScale - the fixed scale
        Returns:
        the fixed scale decimal
        Throws:
        IllegalArgumentException - if the fixed scale is less than the scale of this decimal
      • formatAtLeast

        public String formatAtLeast​(int minDecimalPlaces)
        Formats the decimal to at least the specified number of decimal places.

        With a minimum decimal places of 2, the decimal '12.1' will be formatted as '12.10', and the decimal '12.123' will be formatted as '12.123'

        Calling this method with '0' as the minimum decimal places is equivalent to using toString()..

        Parameters:
        minDecimalPlaces - the minimum number of decimal places, from 0 to 18 inclusive
        Returns:
        the formatted string
      • format

        public String format​(int decimalPlaces,
                             RoundingMode roundingMode)
        Formats the decimal to exactly the specified number of decimal places, specifying the rounding mode.

        With 2 decimal places and rounding mode HALF_UP, the decimal '12.1' will be formatted as '12.10', and the decimal '12.125' will be formatted as '12.13'

        Use RoundingMode.DOWN to truncate at the specified number of decimal places.

        Parameters:
        decimalPlaces - the number of decimal places, from 0 to 18 inclusive
        roundingMode - the rounding mode to use
        Returns:
        the formatted string
      • hashCode

        public int hashCode()
        Overrides:
        hashCode in class Object
      • toString

        public String toString()
        Returns the formal string representation of the decimal.

        This is equivalent to the "plain string" of BigDecimal.

        Overrides:
        toString in class Object
        Returns:
        the plain string