在进行double类型的数字计算时,如果直接用加减乘除的符号进行换算时,总是会碰到有时候差几分。总是很苦恼,尤其是对于涉及到钱的交易系统中,计算的精准性就更显得尤为重要。故放开公式计算的类,供以后参考。
import java.math.BigDecimal; import java.text.DecimalFormat; import org.apache.commons.lang.StringUtils; public class DoubleUtils { private static final int DEF_DIV_SCALE = 10; /** * 提供精确的加法运算 7. * @param v1 被加数 8. * @param v2 加数 9. * @return 两个参数的和 * */ public static int compareWeight(double v1, double v2) { BigDecimal b1 = new BigDecimal(Double.toString(v1)); BigDecimal b2 = new BigDecimal(Double.toString(v2)); b1 = b1.setScale(4, BigDecimal.ROUND_HALF_UP); b2 = b2.setScale(4, BigDecimal.ROUND_HALF_UP); return b1.compareTo(b2); } /** * 金额的比较 * @return */ public static int compareMoney(double v1, double v2) { BigDecimal b1 = new BigDecimal(Double.toString(v1)); BigDecimal b2 = new BigDecimal(Double.toString(v2)); b1 = b1.setScale(2, BigDecimal.ROUND_HALF_UP); b2 = b2.setScale(2, BigDecimal.ROUND_HALF_UP); return b1.compareTo(b2); } /** * 提供精确的加法运算 * @param v1 被加数 * @param v2 加数 * @return 两个参数的和 * */ public static double add(double v1, double v2) { BigDecimal b1 = new BigDecimal(Double.toString(v1)); BigDecimal b2 = new BigDecimal(Double.toString(v2)); return b1.add(b2).doubleValue(); } /** * 提供精确的减法运算 * @return */ public static double substract(double v1, double v2) { BigDecimal b1 = new BigDecimal(Double.toString(v1)); BigDecimal b2 = new BigDecimal(Double.toString(v2)); return b1.subtract(b2).doubleValue(); } /** * 提供精确的乘法运算 * @return */ public static double multiply(double v1, double v2) { BigDecimal b1 = new BigDecimal(Double.toString(v1)); BigDecimal b2 = new BigDecimal(Double.toString(v2)); return b1.multiply(b2).doubleValue(); } /** * * 提供(相对)精确的除法运算,当发生除不尽的情况时, 精确到小数点以后10位,以后的数字四舍五入. * @param v1 被除数 * @param v2 除数 * @return 两个参数的商. */ public static double divide(double v1, double v2) { return divide(v1, v2, DEF_DIV_SCALE); } /** * 提供(相对)精确的除法运算. 当发生除不尽的情况时,由scale参数指 定精度,以后的数字四舍五入. * @param v1 被除数 * @param v2 除数 * @param scale 表示需要精确到小数点以后几位 * @return 两个参数的商 */ public static double divide(double v1, double v2, int scale) { if (scale < 0) { throw new IllegalArgumentException( "The scale must be a positive integer or zero"); } BigDecimal b1 = new BigDecimal(Double.toString(v1)); BigDecimal b2 = new BigDecimal(Double.toString(v2)); return b1.divide(b2, scale, BigDecimal.ROUND_HALF_UP).doubleValue(); } /** * 提供精确的小数位四舍五入处理 * @param v 需要四舍五入的数字 * @param scale 小数点后保留几位 * @return 四舍五入后的结果 */ public static double round(double v, int scale) { if (scale < 0) { throw new IllegalArgumentException( "The scale must be a positive integer or zero"); } BigDecimal b = new BigDecimal(Double.toString(v)); BigDecimal one = new BigDecimal("1"); return b.divide(one, scale, BigDecimal.ROUND_HALF_UP).doubleValue(); } public static double roundMoney(double v) { BigDecimal b = new BigDecimal(Double.toString(v)); BigDecimal one = new BigDecimal("1"); return b.divide(one, 2, BigDecimal.ROUND_HALF_UP).doubleValue(); } public static double roundWeight(double v) { BigDecimal b = new BigDecimal(Double.toString(v)); BigDecimal one = new BigDecimal("1"); return b.divide(one, 4, BigDecimal.ROUND_HALF_UP).doubleValue(); } public static String toMoney(double amount) { DecimalFormat df = new DecimalFormat("0.00"); return df.format(amount); } /** * 将以元为单位的金额转换成以分为单位的金额 * * @param amount * @return */ public static String toMinuteMoney(double amount) { if (compareMoney(amount, 0) == 0) return "0"; DecimalFormat df = new DecimalFormat("0"); return df.format(multiply(roundMoney(amount), 100)); } /** * 将以元为单位的金额转换成以分为单位的金额 * * @param amount * @return */ public static double toYuanMoney(double amount) { if (compareMoney(amount, 0) == 0) return amount; return roundMoney(divide(amount, 100)); } /** * 将以元为单位的金额转换成以分为单位的金额 * * @param amount * @return */ public static double toYuanMoney(String amount) { if (StringUtils.isBlank(amount)) return 0; return roundMoney(divide(Double.parseDouble(amount), 100)); } /** * 将放大了10000倍后的利率还原成原形 * * @param rate * @return */ public static double toRealRate(String rate) { if (StringUtils.isBlank(rate)) return 0; return round(divide(Double.parseDouble(rate), 10000), 5); } /** * 将放大了10000倍后的利率 * * @param rate * @return */ public static String toMaxRate(double rate) { if (compareMoney(rate, 0) == 0) return "0"; DecimalFormat df = new DecimalFormat("0"); return df.format(multiply(roundMoney(rate), 10000)); } public static void main(String[] args) { double str = DoubleUtils.toYuanMoney("1100007"); System.out.println(str); } /*** * 是否为正整数 */ public static boolean isPositiveInteger(double value) { long a = (long) value; if (a != value || a < 0) { return false; } return true; } /*** * 是否为正整数 */ public static boolean isPositiveInteger(String value) { double d = Double.parseDouble(value); long a = (long) d; if (a != d || a < 0) { return false; } return true; } }