/* 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);
}
}