java计算金额保留两位小数精确到分(四舍六入五成双)
四舍六入五成双:
四舍六入五成双是一种比较精确比较科学的计数保留法,是一种数字修约规则。
对于位数很多的近似数,当有效位数确定后,其后面多余的数字应该舍去,只保留有效数字最末一位,这种修约(舍入)规则是"四舍六入五成双",也即"4舍6入5凑偶"这里"四"是指≤4 时舍去,"六"是指≥6时进上,"五"指的是根据5后面的数字来定,当5后有数时,舍5入1;当5后无有效数字时,需要分两种情况来讲:①5前为奇数,舍5入1;②5前为偶数,舍5不进。(0是偶数)
从统计学的角度,"四舍六入五成双"比"四舍五入"要科学,在大量运算时,它使舍入后的结果误差的均值趋于零,而不是像四舍五入那样逢五就入,导致结果偏向大数,使得误差产生积累进而产生系统误差,"四舍六入五成双"使测量结果受到舍入误差的影响降到最低。
在实际情况下,大部分交易的手续费是按单笔计算的,每一笔都对应一个手续费。
例如费率为千分之三,交易1000元,手续费3元,实际到帐997元。交易255元,手续费 255 * 0.003 = 0.765 元。
但是一般做交易时金额都是精确到分的,采用四舍六入五成双方法保留小数点后两位,所以这里手续费是0.76,实际到帐254.24元。
下边是java工具类:
传入返回参数类型都是String
public class StringAmountCalUtil { /** * @Description: 整数相除结果转换成指定位数的百分数 * @param dividend : 被除数(分子) * @param divisor : 除数(分母) * @param digit : 保留几位小数 * @return String */ public static String getPercent(int dividend,int divisor,int digit) { Float result = (float)dividend/(float)divisor; if (result.isNaN()) { return "--"; }else { //获取格式化对象 NumberFormat nt = NumberFormat.getPercentInstance(); //设置百分数精确度,即保留几位小数 nt.setMinimumFractionDigits(digit); String finalResult = nt.format(result); return finalResult; } } /** * 两个数相加 * @param str1 * @param str2 * @return */ public static String add(String str1,String str2) { try { return new BigDecimal(str1).add(new BigDecimal(str2)).toPlainString(); }catch (Exception e){ return null; } } /** * 两个数相乘 * @param str1 * @param str2 * @return */ public static String multiply(String str1,String str2) { try { return new BigDecimal(str1).multiply(new BigDecimal(str2)).toPlainString(); }catch (Exception e){ return null; } } /** * 两个数相减 * @param str1 * @param str2 * @return */ public static String subtract(String str1,String str2) { try { return new BigDecimal(str1).subtract(new BigDecimal(str2)).toPlainString(); }catch (Exception e){ return null; } } /** * 两个数相除 * @param str1 * @param str2 * @return */ public static String divide(String str1,String str2) { try { return new BigDecimal(str1).divide(new BigDecimal(str2),5).toPlainString(); }catch (Exception e){ e.printStackTrace(); return null; } } /** * 四舍六入五五成双 * @param str */ public static String FourUpSixInto(String str){ BigDecimal b1 = new BigDecimal(str); BigDecimal b2 = b1.setScale(2, BigDecimal.ROUND_HALF_EVEN); return b2.toString(); } }
public static void main(String [] args) {
String jine = "255.00";
String feilv = "0.003";
String shouxufei = StringUtil.FourUpSixInto(StringUtil.multiply(jine, feilv));
String realMoney = StringUtil.subtract(jine, shouxufei);
System.out.println("交易金额["+jine+"]\n费率["+feilv+"]\n手续费["+shouxufei+"]\n到帐金额["+realMoney+"]\n");
}
运行结果:
交易金额[255.00]
费率[0.003]
手续费[0.76]
到帐金额[254.24]