1、Java版本
点击查看代码
import com.github.pagehelper.util.StringUtil;
import static cn.hutool.core.convert.Convert.toStr;
import static org.springframework.util.ObjectUtils.isEmpty;
/**
* 数值、精度、修约规则
* <pre>
* 实例代码:
* System.out.println(evenRound(1.1345, 0.001, "四舍五入"));
* System.out.println(evenRound(1.1345, 0.001, "四舍六入"));
* </pre>
*
* @param value:数值
* @param places:精度(1、0.5、10、0.1、0.01...)
* @param even:修约(四舍五入、四舍六入)
* @return {BigDecimal}
*/
public static String evenRound(Object value, Object places, Object even) {
if (places == null || even == null) {
String value2 = toStr(value);
return value2;
}
String value2 = toStr(value);
String places2 = toStr(places);
String even2 = toStr(even);
//数值和精度 不可以为空
if (StringUtil.isEmpty(value2) || StringUtil.isEmpty(places2) || StringUtil.isEmpty(even2)) return value2;
try {
BigDecimal num = new BigDecimal(value2);
Integer decimalPlaces = 0;
//默认是 四舍六入
Integer evenRound = (even2.indexOf("五") > -1 || even2.indexOf("5") > -1 || even2.indexOf("伍") > -1) ? 5 : 6;
if (places2.equals("0.5")) {
//TODO 精度为 0.5 时
//(0.75 * 2).修约 / 2
BigDecimal rule = new BigDecimal("2");//系数
//保留0位小数
decimalPlaces = 0;
if (evenRound == 5) {
//四舍五入
value2 = ((num.multiply(rule)).setScale(decimalPlaces, BigDecimal.ROUND_HALF_UP).divide(rule, 4, BigDecimal.ROUND_HALF_UP)).toString();
} else {
//四舍六入
value2 = ((num.multiply(rule)).setScale(decimalPlaces, BigDecimal.ROUND_HALF_EVEN).divide(rule, 4, BigDecimal.ROUND_HALF_EVEN)).toString();
}
value2 = numDecimal(value2, 1);
} else if (places2.equals("5")) {
//TODO 精度为 ”5“ 时 ,个位只有(0 | 5)
//(0.75 * 0.2).修约 / 0.2
BigDecimal rule = new BigDecimal("0.2");//系数
//保留0位小数
decimalPlaces = 0;
if (evenRound == 5) {
//四舍五入
value2 = ((num.multiply(rule)).setScale(decimalPlaces, BigDecimal.ROUND_HALF_UP).divide(rule, 4, BigDecimal.ROUND_HALF_UP)).toString();
} else {
//四舍六入
value2 = ((num.multiply(rule)).setScale(decimalPlaces, BigDecimal.ROUND_HALF_EVEN).divide(rule, 4, BigDecimal.ROUND_HALF_EVEN)).toString();
}
value2 = numDecimal(value2, 0);
} else if (places2.equals("10")) {
//TODO 精度为 ”10“ 时
//(0.75 / 10).修约 * 10
BigDecimal rule = new BigDecimal("10");//系数
//保留0位小数
decimalPlaces = 0;
if (evenRound == 5) {
//四舍五入
value2 = ((num.divide(rule)).setScale(decimalPlaces, BigDecimal.ROUND_HALF_UP).multiply(rule)).toString();
} else {
//四舍六入
value2 = ((num.divide(rule)).setScale(decimalPlaces, BigDecimal.ROUND_HALF_EVEN).multiply(rule)).toString();
}
} else {
//0.1、0.01
String[] split = places2.split("\\.");//截取小数点
if (split.length > 1) {
//拿到小数点后几位,就保留几位小数
decimalPlaces = split[1].length();
}
if (evenRound == 5) {
//四舍五入
value2 = num.setScale(decimalPlaces, BigDecimal.ROUND_HALF_UP).toString();
} else {
//四舍六入
value2 = num.setScale(decimalPlaces, BigDecimal.ROUND_HALF_EVEN).toString();
}
value2 = numDecimal(value2, decimalPlaces);
}
} catch (Exception e) {
System.err.println(value + "," + places + "," + even + "\t修约规则有误:" + e.getMessage());
}
return value2;
//规则:
//四舍六入五考虑,
//五后非零就进一,
//五后皆零看奇偶,
//五前为偶应舍去,
//五前为奇要进一。
}
/**
* 小数位不够自动补 “0”
*
* @param num {数值}
* @param len {保留几位小数}
*/
public static String numDecimal(String num, int len) {
num = org.springframework.util.ObjectUtils.isEmpty(num) ? "0" : toStr(num);
len = org.springframework.util.ObjectUtils.isEmpty(len) ? 0 : len;
if (len == 0) return num.split("\\.")[0];
String decimal;
if (num.indexOf(".") == -1 && len != 0) num += ".0";
String[] split = num.split("\\.");
decimal = split[1];//12
num = split[0];
if (decimal.length() > len) {
decimal = decimal.substring(0, len);
} else {
while (decimal.length() != len) {
decimal += "0";
}
}
return num + "." + decimal;
}
2、JavaScript版本
点击查看代码
/**
* 数值修约算法(四舍六入)
* @param num
* @param decimalPlaces{number}
* @returns {number}
* @see https://www.jianshu.com/p/d329fe017520
*/
export function sixRound(num, decimalPlaces) {
let d = decimalPlaces || 0;
let m = Math.pow(10, d);
let n = +(d ? num * m : num).toFixed(8);
let i = Math.floor(n), f = n - i;
let e = 1e-8;
let r = (f > 0.5 - e && f < 0.5 + e) ?
((i % 2 === 0) ? i : i + 1) : Math.round(n);
return d ? r / m : r;
}