/* BigDecimals.java Purpose: Description: History: Thu Apr 17 10:25:07 2003, Created by tomyeh Copyright (C) 2002 Potix Corporation. All Rights Reserved. {{IS_RIGHT This program is distributed under LGPL Version 2.1 in the hope that it will be useful, but WITHOUT ANY WARRANTY. }}IS_RIGHT */ package org.zkoss.math; import java.math.BigDecimal; import java.math.BigInteger; import java.text.DecimalFormatSymbols; import java.util.Locale; import org.zkoss.lang.Objects; import org.zkoss.util.Locales; /** * Utilities and constants of big decimals. * * @author tomyeh */ public class BigDecimals { /** Represents 0 in big decimal. * @see #ONE * @see #MINUS_ONE */ public static final BigDecimal ZERO = Objects.ZERO_BIG_DECIMAL; /** Represents 1 in big decimal. * @see #ZERO * @see #MINUS_ONE */ public static final BigDecimal ONE = new BigDecimal(BigInteger.ONE); /** Represents -1 in big decimal. * @see #ZERO * @see #ONE */ public static final BigDecimal MINUS_ONE = new BigDecimal(BigInteger.ONE.negate()); /** Represents our number precision. */ public static final int NUMBER_PRECISION = 38; /** Represents our number scale. */ public static final int NUMBER_SCALE = 6; /** Represents our fine number precision. */ public static final int FINE_NUMBER_PRECISION = 20; /** Represents our fine number scale. */ public static final int FINE_NUMBER_SCALE = 8; /** Converts a double to a big decimal with a scale. * * <p>It is strongly deprecated to use new Decimal(double) since * the scale is unpredictable and usually surprising. * For example, BigDecimal(.1) will becomes * .1000000000000000055511151231257827021181583404541015625. * On the other hand, BigDecimal("0.1") will be 0.1 correctly. * * @param scale the BigDecimal's scale * @param roundingMode the rounding mode */ public static final BigDecimal toBigDecimal(double v, int scale, int roundingMode) { return new BigDecimal(v).setScale(scale, roundingMode); } /** Converts a double to a big decimal with a scale. * It uses {@link BigDecimal#ROUND_HALF_UP}. */ public static final BigDecimal toBigDecimal(double v, int scale) { return toBigDecimal(v, scale, BigDecimal.ROUND_HALF_UP); } /** Converts an integer to a big decimal with a scale. */ public static final BigDecimal toBigDecimal(int v, int scale) { return new BigDecimal(BigIntegers.toBigInteger(v), scale); } /** Converts an integer to a big decimal with a scale. */ public static final BigDecimal toBigDecimal(long v, int scale) { return new BigDecimal(BigIntegers.toBigInteger(v), scale); } /** Converts an integer to a big decimal with a scale without. * losing precision -- zero scale in this case. */ public static final BigDecimal toBigDecimal(int v) { return v == 0 ? ZERO: new BigDecimal(BigIntegers.toBigInteger(v)); } /** Converts a long to a big decimal with a scale without. * losing precision -- zero scale in this case. */ public static final BigDecimal toBigDecimal(long v) { return v == 0 ? ZERO: new BigDecimal(BigIntegers.toBigInteger(v)); } /** Converts a short to a big decimal with a scale without. * losing precision -- zero scale in this case. */ public static final BigDecimal toBigDecimal(short v) { return v == 0 ? ZERO: new BigDecimal(BigIntegers.toBigInteger(v)); } /** Converts a byte to a big decimal with a scale without. * losing precision -- zero scale in this case. */ public static final BigDecimal toBigDecimal(byte v) { return v == 0 ? ZERO: new BigDecimal(BigIntegers.toBigInteger(v)); } /** Converts an integer to a big decimal with a scale without. * losing precision -- zero scale in this case. */ public static final BigDecimal toBigDecimal(Integer v) { return toBigDecimal(v.intValue()); } /** Converts a long to a big decimal with a scale without. * losing precision -- zero scale in this case. */ public static final BigDecimal toBigDecimal(Long v) { return toBigDecimal(v.longValue()); } /** Converts a short to a big decimal with a scale without. * losing precision -- zero scale in this case. */ public static final BigDecimal toBigDecimal(Short v) { return toBigDecimal(v.shortValue()); } /** Converts a byte to a big decimal with a scale without. * losing precision -- zero scale in this case. */ public static final BigDecimal toBigDecimal(Byte v) { return toBigDecimal(v.byteValue()); } /** @deprecated As of release 6.0.0, use BigDecimal.toPlainString() directly * (since we don't support JDK 1.4) anymore. */ public static final String toPlainString(BigDecimal bd) { return bd.toPlainString(); } /** * Return a string representation of this BigDecimal without an exponent * field, which respects the given locale. * @param locale if null, the current user locale is used. * @since 5.0.10 */ public static final String toLocaleString(BigDecimal bd, Locale locale) { if (locale == null) locale = Locales.getCurrent(); final DecimalFormatSymbols symbols = new DecimalFormatSymbols(locale); final char DECIMAL = symbols.getDecimalSeparator(); final char MINUS = symbols.getMinusSign(); // only replace MINUS and DECIMAL as toPlainString() implementation // only involves these two chars. return toPlainString(bd).replace('.', DECIMAL).replace('-', MINUS); } }