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

org.javamoney.moneta.RoundedMoney Maven / Gradle / Ivy

Go to download

JSR 354 provides an API for representing, transporting, and performing comprehensive calculations with Money and Currency. This module implements JSR 354.

There is a newer version: 1.4.1
Show newest version
/**
 * Copyright (c) 2012, 2014, Credit Suisse (Anatole Tresch), Werner Keil and others by the @author tag.
 *
 * 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.javamoney.moneta;

import javax.money.CurrencyUnit;
import javax.money.Monetary;
import javax.money.MonetaryAmount;
import javax.money.MonetaryAmountFactory;
import javax.money.MonetaryContext;
import javax.money.MonetaryContextBuilder;
import javax.money.MonetaryException;
import javax.money.MonetaryOperator;
import javax.money.MonetaryQuery;
import javax.money.NumberValue;
import javax.money.RoundingQueryBuilder;

import org.javamoney.moneta.internal.RoundedMoneyAmountBuilder;
import org.javamoney.moneta.spi.DefaultNumberValue;
import org.javamoney.moneta.spi.MoneyUtils;

import javax.money.format.MonetaryAmountFormat;

import java.io.Serializable;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.math.MathContext;
import java.math.RoundingMode;
import java.util.Objects;

/**
 * Platform RI: Default immutable implementation of {@link MonetaryAmount} based on
 * {@link BigDecimal} for the numeric representation.
 * 

* As required by {@link MonetaryAmount} this class is final, thread-safe, immutable and * serializable. * * @author Anatole Tresch * @author Werner Keil * @version 0.6.1 */ public final class RoundedMoney implements MonetaryAmount, Comparable, Serializable { /** * serialVersionUID. */ private static final long serialVersionUID = 366517590511294389L; /** * The default {@link MonetaryContext} applied. */ public static final MonetaryContext DEFAULT_MONETARY_CONTEXT = MonetaryContextBuilder.of(RoundedMoney.class) .set("MonetaryRounding", Monetary.getDefaultRounding()). build(); /** * The currency of this amount. */ private final CurrencyUnit currency; /** * the {@link MonetaryContext} used by this instance, e.g. on division. */ private final MonetaryContext monetaryContext; /** * The numeric part of this amount. */ private final BigDecimal number; /** * The rounding to be done. */ private MonetaryOperator rounding; /** * Creates a new instance os {@link RoundedMoney}. * * @param currency the currency, not null. * @param number the amount, not null. */ public RoundedMoney(Number number, CurrencyUnit currency, MonetaryOperator rounding) { this(number, currency, null, rounding); } public RoundedMoney(Number number, CurrencyUnit currency, MathContext mathContext) { Objects.requireNonNull(currency, "Currency is required."); this.currency = currency; this.rounding = Monetary.getRounding(RoundingQueryBuilder.of().set(mathContext).build()); this.monetaryContext = DEFAULT_MONETARY_CONTEXT.toBuilder().set("MonetaryRounding", rounding).set(mathContext) .build(); Objects.requireNonNull(number, "Number is required."); checkNumber(number); this.number = MoneyUtils.getBigDecimal(number, monetaryContext); } public RoundedMoney(Number number, CurrencyUnit currency, MonetaryContext context, MonetaryOperator rounding) { Objects.requireNonNull(currency, "Currency is required."); this.currency = currency; Objects.requireNonNull(number, "Number is required."); checkNumber(number); MonetaryContextBuilder b = DEFAULT_MONETARY_CONTEXT.toBuilder(); if (rounding!=null) { this.rounding = rounding; } else { if (context != null) { MathContext mc = context.get(MathContext.class); if (mc == null) { RoundingMode rm = context.get(RoundingMode.class); if (rm != null) { Integer scale = context.getInt("scale"); if(scale==null){ scale = 2; } b.set(rm); b.set("scale", scale); this.rounding = Monetary .getRounding(RoundingQueryBuilder.of().setScale(scale).set(rm).build()); } } else { b.set(mc.getRoundingMode()); b.set("scale", 2); this.rounding = Monetary.getRounding(RoundingQueryBuilder.of().set(mc).setScale(2).build()); } if (this.rounding == null) { this.rounding = Monetary.getDefaultRounding(); } } } b.set("MonetaryRounding", this.rounding); if (context != null) { b.importContext(context); } this.monetaryContext = b.build(); this.number = MoneyUtils.getBigDecimal(number, monetaryContext); } // Static Factory Methods /** * Translates a {@code BigDecimal} value and a {@code CurrencyUnit} currency into a * {@code Money}. * * @param number numeric value of the {@code Money}. * @param currency currency unit of the {@code Money}. * @return a {@code Money} combining the numeric value and currency unit. */ public static RoundedMoney of(BigDecimal number, CurrencyUnit currency) { return new RoundedMoney(number, currency, Monetary.getDefaultRounding()); } /** * Translates a {@code BigDecimal} value and a {@code CurrencyUnit} currency into a * {@code Money}. * * @param number numeric value of the {@code Money}. * @param currency currency unit of the {@code Money}. * @param rounding The rounding to be applied. * @return a {@code Money} combining the numeric value and currency unit. */ public static RoundedMoney of(BigDecimal number, CurrencyUnit currency, MonetaryOperator rounding) { return new RoundedMoney(number, currency, rounding); } /** * Translates a {@code BigDecimal} value and a {@code CurrencyUnit} currency into a * {@code Money}. * * @param number numeric value of the {@code Money}. * @param currency currency unit of the {@code Money}. * @param mathContext the {@link MathContext} to be used. * @return a {@code Money} combining the numeric value and currency unit. */ public static RoundedMoney of(BigDecimal number, CurrencyUnit currency, MathContext mathContext) { return new RoundedMoney(number, currency, mathContext); } /** * Static factory method for creating a new instance of {@link RoundedMoney} . * * @param currency The target currency, not null. * @param number The numeric part, not null. * @return A new instance of {@link RoundedMoney}. */ public static RoundedMoney of(Number number, CurrencyUnit currency) { return new RoundedMoney(number, currency, (MonetaryOperator) null); } /** * Static factory method for creating a new instance of {@link RoundedMoney} . * * @param currency The target currency, not null. * @param number The numeric part, not null. * @param rounding The rounding to be applied. * @return A new instance of {@link RoundedMoney}. */ public static RoundedMoney of(Number number, CurrencyUnit currency, MonetaryOperator rounding) { return new RoundedMoney(number, currency, rounding); } /** * Static factory method for creating a new instance of {@link RoundedMoney} . * * @param currency The target currency, not null. * @param number The numeric part, not null. * @return A new instance of {@link RoundedMoney}. */ public static RoundedMoney of(Number number, CurrencyUnit currency, MonetaryContext monetaryContext) { return new RoundedMoney(number, currency, DEFAULT_MONETARY_CONTEXT.toBuilder().importContext(monetaryContext).build(), null); } /** * Static factory method for creating a new instance of {@link RoundedMoney} . * * @param currency The target currency, not null. * @param number The numeric part, not null. * @param monetaryContext the {@link MonetaryContext} to be used. * @param rounding The rounding to be applied. * @return A new instance of {@link RoundedMoney}. */ public static RoundedMoney of(CurrencyUnit currency, Number number, MonetaryContext monetaryContext, MonetaryOperator rounding) { return new RoundedMoney(number, currency, DEFAULT_MONETARY_CONTEXT.toBuilder().importContext(monetaryContext).build(), rounding); } /** * Static factory method for creating a new instance of {@link RoundedMoney} . * * @param currencyCode The target currency as ISO currency code. * @param number The numeric part, not null. * @return A new instance of {@link RoundedMoney}. */ public static RoundedMoney of(Number number, String currencyCode) { return new RoundedMoney(number, Monetary.getCurrency(currencyCode), Monetary.getDefaultRounding()); } /** * Static factory method for creating a new instance of {@link RoundedMoney} . * * @param currencyCode The target currency as ISO currency code. * @param number The numeric part, not null. * @param rounding The rounding to be applied. * @return A new instance of {@link RoundedMoney}. */ public static RoundedMoney of(Number number, String currencyCode, MonetaryOperator rounding) { return new RoundedMoney(number, Monetary.getCurrency(currencyCode), rounding); } /** * Static factory method for creating a new instance of {@link RoundedMoney} . * * @param currencyCode The target currency as ISO currency code. * @param number The numeric part, not null. * @return A new instance of {@link RoundedMoney}. */ public static RoundedMoney of(Number number, String currencyCode, MonetaryContext monetaryContext) { return new RoundedMoney(number, Monetary.getCurrency(currencyCode), DEFAULT_MONETARY_CONTEXT.toBuilder().importContext(monetaryContext).build(), null); } /** * Static factory method for creating a new instance of {@link RoundedMoney} . * * @param currencyCode The target currency as ISO currency code. * @param number The numeric part, not null. * @param rounding The rounding to be applied. * @return A new instance of {@link RoundedMoney}. */ public static RoundedMoney of(String currencyCode, Number number, MonetaryContext monetaryContext, MonetaryOperator rounding) { return new RoundedMoney(number, Monetary.getCurrency(currencyCode), DEFAULT_MONETARY_CONTEXT.toBuilder().importContext(monetaryContext).build(), rounding); } /* * (non-Javadoc) * @see MonetaryAmount#getCurrency() */ @Override public CurrencyUnit getCurrency() { return currency; } /** * Access the {@link MathContext} used by this instance. * * @return the {@link MathContext} used, never null. */ @Override public MonetaryContext getContext() { return this.monetaryContext; } @Override public RoundedMoney abs() { if (this.isPositiveOrZero()) { return this; } return this.negate(); } // Arithmetic Operations @Override public RoundedMoney add(MonetaryAmount amount) { MoneyUtils.checkAmountParameter(amount, this.currency); if (amount.isZero()) { return this; } return new RoundedMoney(this.number.add(amount.getNumber().numberValue(BigDecimal.class)), this.currency, this.rounding).with(rounding); } /* * (non-Javadoc) * @see MonetaryAmount#divide(MonetaryAmount) */ @Override public RoundedMoney divide(Number divisor) { BigDecimal bd = MoneyUtils.getBigDecimal(divisor); if (isOne(bd)) { return this; } RoundingMode rm = this.monetaryContext.get(RoundingMode.class); if(rm==null){ rm = RoundingMode.HALF_EVEN; } BigDecimal dec = this.number.divide(bd, rm); return new RoundedMoney(dec, this.currency, this.rounding).with(rounding); } /* * (non-Javadoc) * @see MonetaryAmount#divideAndRemainder(MonetaryAmount) */ @Override public RoundedMoney[] divideAndRemainder(Number divisor) { BigDecimal bd = MoneyUtils.getBigDecimal(divisor); if (isOne(bd)) { return new RoundedMoney[]{this, new RoundedMoney(0L, getCurrency(), this.rounding)}; } MathContext mc = this.monetaryContext.get(MathContext.class); if(mc==null){ mc = MathContext.DECIMAL64; } BigDecimal[] dec = this.number.divideAndRemainder(MoneyUtils.getBigDecimal(divisor), mc); return new RoundedMoney[]{new RoundedMoney(dec[0], this.currency, this.rounding), new RoundedMoney(dec[1], this.currency, this.rounding).with(rounding)}; } /* * (non-Javadoc) * @see MonetaryAmount#divideToIntegralValue(Number) )D */ @Override public RoundedMoney divideToIntegralValue(Number divisor) { MathContext mc = this.monetaryContext.get(MathContext.class); if(mc==null){ mc = MathContext.DECIMAL64; } BigDecimal dec = this.number.divideToIntegralValue(MoneyUtils.getBigDecimal(divisor), mc); return new RoundedMoney(dec, this.currency, this.rounding); } /* * (non-Javadoc) * @see MonetaryAmount#multiply(Number) */ @Override public RoundedMoney multiply(Number multiplicand) { BigDecimal bd = MoneyUtils.getBigDecimal(multiplicand); if (isOne(bd)) { return this; } MathContext mc = this.monetaryContext.get(MathContext.class); if(mc==null){ mc = MathContext.DECIMAL64; } BigDecimal dec = this.number.multiply(bd, mc); return new RoundedMoney(dec, this.currency, this.rounding).with(rounding); } /* * (non-Javadoc) * @see MonetaryAmount#negate() */ @Override public RoundedMoney negate() { MathContext mc = this.monetaryContext.get(MathContext.class); if(mc==null){ mc = MathContext.DECIMAL64; } return new RoundedMoney(this.number.negate(mc), this.currency, this.rounding); } /* * (non-Javadoc) * @see MonetaryAmount#plus() */ @Override public RoundedMoney plus() { MathContext mc = this.monetaryContext.get(MathContext.class); if(mc==null){ mc = MathContext.DECIMAL64; } return new RoundedMoney(this.number.plus(mc), this.currency, this.rounding); } /* * (non-Javadoc) * @see MonetaryAmount#subtract(MonetaryAmount) */ @Override public RoundedMoney subtract(MonetaryAmount subtrahend) { MoneyUtils.checkAmountParameter(subtrahend, this.currency); if (subtrahend.isZero()) { return this; } MathContext mc = this.monetaryContext.get(MathContext.class); if(mc==null){ mc = MathContext.DECIMAL64; } return new RoundedMoney(this.number.subtract(subtrahend.getNumber().numberValue(BigDecimal.class), mc), this.currency, this.rounding); } /* * (non-Javadoc) * @see MonetaryAmount#pow(int) */ public RoundedMoney pow(int n) { MathContext mc = this.monetaryContext.get(MathContext.class); if(mc==null){ mc = MathContext.DECIMAL64; } return new RoundedMoney(this.number.pow(n, mc), this.currency, this.rounding).with(rounding); } /* * (non-Javadoc) * @see MonetaryAmount#ulp() */ public RoundedMoney ulp() { return new RoundedMoney(this.number.ulp(), this.currency, this.rounding); } /* * (non-Javadoc) * @see MonetaryAmount#remainder(Number) */ @Override public RoundedMoney remainder(Number divisor) { MathContext mc = this.monetaryContext.get(MathContext.class); if(mc==null){ mc = MathContext.DECIMAL64; } return new RoundedMoney(this.number.remainder(MoneyUtils.getBigDecimal(divisor), mc), this.currency, this.rounding); } /* * (non-Javadoc) * @see MonetaryAmount#scaleByPowerOfTen(int) */ @Override public RoundedMoney scaleByPowerOfTen(int n) { return new RoundedMoney(this.number.scaleByPowerOfTen(n), this.currency, this.rounding); } /* * (non-Javadoc) * @see MonetaryAmount#isZero() */ @Override public boolean isZero() { return this.number.signum() == 0; } /* * (non-Javadoc) * @see MonetaryAmount#isPositive() */ @Override public boolean isPositive() { return signum() == 1; } /* * (non-Javadoc) * @see MonetaryAmount#isPositiveOrZero() */ @Override public boolean isPositiveOrZero() { return signum() >= 0; } /* * (non-Javadoc) * @see MonetaryAmount#isNegative() */ @Override public boolean isNegative() { return signum() == -1; } /* * (non-Javadoc) * @see MonetaryAmount#isNegativeOrZero() */ @Override public boolean isNegativeOrZero() { return signum() <= 0; } /* * (non-Javadoc) * @see MonetaryAmount#with(java.lang.Number) */ public RoundedMoney with(Number amount) { checkNumber(amount); return new RoundedMoney(MoneyUtils.getBigDecimal(amount), this.currency, this.rounding); } /** * Creates a new Money instance, by just replacing the {@link CurrencyUnit}. * * @param currency the currency unit to be replaced, not {@code null} * @return the new amount with the same numeric value and {@link MathContext}, but the new * {@link CurrencyUnit}. */ public RoundedMoney with(CurrencyUnit currency) { Objects.requireNonNull(currency, "currency required"); return new RoundedMoney(asType(BigDecimal.class), currency, this.rounding); } /* * (non-Javadoc) * @see MonetaryAmount#with(CurrencyUnit, java.lang.Number) */ public RoundedMoney with(CurrencyUnit currency, Number amount) { checkNumber(amount); return new RoundedMoney(MoneyUtils.getBigDecimal(amount), currency, this.rounding); } /* * (non-Javadoc) * @see MonetaryAmount#getScale() */ public int getScale() { return this.number.scale(); } /* * (non-Javadoc) * @see MonetaryAmount#getPrecision() */ public int getPrecision() { return this.number.precision(); } /* * (non-Javadoc) * @see MonetaryAmount#signum() */ @Override public int signum() { return this.number.signum(); } /* * (non-Javadoc) * @see MonetaryAmount#lessThan(MonetaryAmount) */ @Override public boolean isLessThan(MonetaryAmount amount) { MoneyUtils.checkAmountParameter(amount, this.currency); return number.stripTrailingZeros() .compareTo(amount.getNumber().numberValue(BigDecimal.class).stripTrailingZeros()) < 0; } /* * (non-Javadoc) * @see MonetaryAmount#lessThanOrEqualTo(MonetaryAmount) */ @Override public boolean isLessThanOrEqualTo(MonetaryAmount amount) { MoneyUtils.checkAmountParameter(amount, this.currency); return number.stripTrailingZeros() .compareTo(amount.getNumber().numberValue(BigDecimal.class).stripTrailingZeros()) <= 0; } /* * (non-Javadoc) * @see MonetaryAmount#greaterThan(MonetaryAmount) */ @Override public boolean isGreaterThan(MonetaryAmount amount) { MoneyUtils.checkAmountParameter(amount, this.currency); return number.stripTrailingZeros() .compareTo(amount.getNumber().numberValue(BigDecimal.class).stripTrailingZeros()) > 0; } /* * (non-Javadoc) * @see MonetaryAmount#greaterThanOrEqualTo(MonetaryAmount ) #see */ @Override public boolean isGreaterThanOrEqualTo(MonetaryAmount amount) { MoneyUtils.checkAmountParameter(amount, this.currency); return number.stripTrailingZeros() .compareTo(amount.getNumber().numberValue(BigDecimal.class).stripTrailingZeros()) >= 0; } /* * (non-Javadoc) * @see MonetaryAmount#isEqualTo(MonetaryAmount) */ @Override public boolean isEqualTo(MonetaryAmount amount) { MoneyUtils.checkAmountParameter(amount, this.currency); return number.stripTrailingZeros() .compareTo(amount.getNumber().numberValue(BigDecimal.class).stripTrailingZeros()) == 0; } /* * (non-Javadoc) * @see MonetaryAmount#isNotEqualTo(MonetaryAmount) */ public boolean isNotEqualTo(MonetaryAmount amount) { MoneyUtils.checkAmountParameter(amount, this.currency); return number.stripTrailingZeros() .compareTo(amount.getNumber().numberValue(BigDecimal.class).stripTrailingZeros()) != 0; } /* * }(non-Javadoc) * @see MonetaryAmount#adjust(org.javamoney.bp.AmountAdjuster) */ @Override public RoundedMoney with(MonetaryOperator operator) { Objects.requireNonNull(operator); try { return RoundedMoney.from(operator.apply(this)); } catch (MonetaryException | ArithmeticException e) { throw e; } catch (Exception e) { throw new MonetaryException("Query failed: " + operator, e); } } public static RoundedMoney from(MonetaryAmount amt) { if (amt.getClass() == RoundedMoney.class) { return (RoundedMoney) amt; } if (amt.getClass() == FastMoney.class) { return RoundedMoney.of(amt.getNumber().numberValue(BigDecimal.class), amt.getCurrency()); } else if (amt.getClass() == Money.class) { return RoundedMoney.of(amt.getNumber().numberValue(BigDecimal.class), amt.getCurrency()); } return RoundedMoney.of(amt.getNumber().numberValue(BigDecimal.class), amt.getCurrency()); } /** * Obtains an instance of RoundedMoney from a text string such as 'EUR * 25.25'. * * @param text the input text, not null. * @return RoundedMoney instance * @throws NullPointerException * @throws NumberFormatException * @throws javax.money.UnknownCurrencyException */ public static RoundedMoney parse(CharSequence text) { return parse(text, DEFAULT_FORMATTER); } /** * Obtains an instance of FastMoney from a text using specific formatter. * * @param text the text to parse not null * @param formatter the formatter to use not null * @return RoundedMoney instance */ public static RoundedMoney parse(CharSequence text, MonetaryAmountFormat formatter) { return from(formatter.parse(text)); } private static final ToStringMonetaryAmountFormat DEFAULT_FORMATTER = ToStringMonetaryAmountFormat .of(ToStringMonetaryAmountFormat.ToStringMonetaryAmountFormatStyle.ROUNDED_MONEY); /* * }(non-Javadoc) * @see MonetaryAmount#adjust(org.javamoney.bp.AmountAdjuster) */ @Override public T query(MonetaryQuery query) { Objects.requireNonNull(query); try { return query.queryFrom(this); } catch (MonetaryException | ArithmeticException e) { throw e; } catch (Exception e) { throw new MonetaryException("Query failed: " + query, e); } } /* * @see MonetaryAmount#asType(java.lang.Class) */ @SuppressWarnings("unchecked") public T asType(Class type) { if (BigDecimal.class.equals(type)) { return (T) this.number; } if (Number.class.equals(type)) { return (T) this.number; } if (Double.class.equals(type)) { return (T) Double.valueOf(this.number.doubleValue()); } if (Float.class.equals(type)) { return (T) Float.valueOf(this.number.floatValue()); } if (Long.class.equals(type)) { return (T) Long.valueOf(this.number.longValue()); } if (Integer.class.equals(type)) { return (T) Integer.valueOf(this.number.intValue()); } if (Short.class.equals(type)) { return (T) Short.valueOf(this.number.shortValue()); } if (Byte.class.equals(type)) { return (T) Byte.valueOf(this.number.byteValue()); } if (BigInteger.class.equals(type)) { return (T) this.number.toBigInteger(); } throw new IllegalArgumentException("Unsupported representation type: " + type); } /* * }(non-Javadoc) * @see MonetaryAmount#asType(java.lang.Class, org.javamoney.bp.Rounding) */ public T asType(Class type, MonetaryOperator adjuster) { RoundedMoney amount = (RoundedMoney) adjuster.apply(this); return amount.asType(type); } /* * (non-Javadoc) * @see java.lang.Object#toString() */ @Override public String toString() { return currency.getCurrencyCode() + ' ' + number; } /* * (non-Javadoc) * @see java.lang.Object#hashCode() */ @Override public int hashCode() { return Objects.hash(currency, asNumberStripped()); } /* * (non-Javadoc) * @see java.lang.Object#equals(java.lang.Object) */ @Override public boolean equals(Object obj) { if (obj == this) { return true; } if (obj instanceof RoundedMoney) { RoundedMoney other = (RoundedMoney) obj; return Objects.equals(currency, other.currency) && Objects.equals(asNumberStripped(), other.asNumberStripped()); } return false; } /* * @see java.lang.Comparable#compareTo(java.lang.Object) */ @Override public int compareTo(MonetaryAmount o) { Objects.requireNonNull(o); int compare; if (this.currency.equals(o.getCurrency())) { compare = asNumberStripped().compareTo(RoundedMoney.from(o).asNumberStripped()); } else { compare = this.currency.getCurrencyCode().compareTo(o.getCurrency().getCurrencyCode()); } return compare; } /* * (non-Javadoc) * @see MonetaryAmount#getNumber() */ @Override public NumberValue getNumber() { return new DefaultNumberValue(number); } /** * Method that returns BigDecimal.ZERO, if {@link #isZero()}, and #number * {@link #stripTrailingZeros()} in all other cases. * * @return the stripped number value. */ public BigDecimal asNumberStripped() { if (isZero()) { return BigDecimal.ZERO; } return this.number.stripTrailingZeros(); } /** * Internal method to check for correct number parameter. * * @param number the number to check. * @throws IllegalArgumentException If the number is null */ private void checkNumber(Number number) { Objects.requireNonNull(number, "Number is required."); } @Override public RoundedMoney multiply(long amount) { if (amount == 1L) { return this; } return multiply(MoneyUtils.getBigDecimal(amount)); } @Override public RoundedMoney multiply(double amount) { Money.checkNoInfinityOrNaN(amount); if (amount == 1.0d) { return this; } return multiply(MoneyUtils.getBigDecimal(amount)); } @Override public RoundedMoney divide(long amount) { if (amount == 1L) { return this; } return divide(MoneyUtils.getBigDecimal(amount)); } @Override public RoundedMoney divide(double amount) { if (Money.isInfinityAndNotNaN(amount)) { return new RoundedMoney(0L, getCurrency(), this.monetaryContext, this.rounding); } if (amount == 1.0d) { return this; } return divide(MoneyUtils.getBigDecimal(amount)); } @Override public RoundedMoney remainder(long amount) { return remainder(MoneyUtils.getBigDecimal(amount)); } @Override public RoundedMoney remainder(double amount) { if (Money.isInfinityAndNotNaN(amount)) { return new RoundedMoney(0L, getCurrency(), this.monetaryContext, this.rounding); } return remainder(MoneyUtils.getBigDecimal(amount)); } @Override public RoundedMoney[] divideAndRemainder(long amount) { return divideAndRemainder(MoneyUtils.getBigDecimal(amount)); } @Override public RoundedMoney[] divideAndRemainder(double amount) { if (Money.isInfinityAndNotNaN(amount)) { RoundedMoney zero = new RoundedMoney(0L, getCurrency(), this.monetaryContext, this.rounding); return new RoundedMoney[]{zero, zero}; } return divideAndRemainder(MoneyUtils.getBigDecimal(amount)); } @Override public RoundedMoney stripTrailingZeros() { if (isZero()) { return of(BigDecimal.ZERO, getCurrency()); } return of(this.number.stripTrailingZeros(), getCurrency()); } @Override public RoundedMoney divideToIntegralValue(long divisor) { return divideToIntegralValue(MoneyUtils.getBigDecimal(divisor)); } @Override public RoundedMoney divideToIntegralValue(double divisor) { return divideToIntegralValue(MoneyUtils.getBigDecimal(divisor)); } @Override public MonetaryAmountFactory getFactory() { return new RoundedMoneyAmountBuilder().setAmount(this); } private boolean isOne(Number number) { BigDecimal bd = MoneyUtils.getBigDecimal(number); try { return bd.scale() == 0 && bd.longValueExact() == 1L; } catch (Exception e) { // The only way to end up here is that longValueExact throws an ArithmeticException, // so the amount is definitively not equal to 1. return false; } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy