金额字段改成千分位加2位小数格式+toFixed四舍五入不精确的解决方法
- 一、金额字段改成千分位加2位小数格式
- 二、toFixed四舍五入不精确的解决方法
- 1.重写toFixed方法
- 2.对金额格式的扩展
- 碎碎念
一、金额字段改成千分位加2位小数格式
如果不在意四舍五入问题,一条语句就能解决
(price.toFixed(2)+"").replace(/(\d)(?=(\d{3})+(?!\d))/g, "$1,")
如果在意四舍五入问题,自己测试一下,你会发现toFixed方法四舍五入的方式和人的惯用思维是不一样的,比如:
console.log(1.265.toFixed(2))
console.log(12.225.toFixed(2))
console.log(123.355.toFixed(2))
console.log((5555555.555.toFixed(2)+"").replace(/(\d)(?=(\d{3})+(?!\d))/g, "$1,"))
输出结果:
二、toFixed四舍五入不精确的解决方法
1.重写toFixed方法
网上搜到了很多不同的方法,对比后觉得重写toFixed能从根源上解决问题,之后的人在这个项目里使用toFixed也可以避免出现四舍五入不精确的bug。
//重写toFixed方法,解决四舍五入不稳定问题
Number.prototype.toReFixed=function (d) {
var s=this+"";
if(!d)d=0;
if(s.indexOf(".")==-1)s+=".";
s+=new Array(d+1).join("0");
if(new RegExp("^(-|\\+)?(\\d+(\\.\\d{0,"+(d+1)+"})?)\\d*$").test(s)){
var s="0"+RegExp.$2,pm=RegExp.$1,a=RegExp.$3.length,b=true;
if(a==d+2){
a=s.match(/\d/g);
if(parseInt(a[a.length-1])>4){
for(var i=a.length-2;i>=0;i--){
a[i]=parseInt(a[i])+1;
if(a[i]==10){
a[i]=0;
b=i!=1;
}else break;
}
}
s=a.join("").replace(new RegExp("(\\d+)(\\d{"+d+"})\\d$"),"$1.$2");
}if(b)s=s.substr(1);
return (pm+s).replace(/\.$/,"");
}return this+"";
}
但是,这里为了方便区分原来的toFixed和自己改的toFixed,本人命名为toReFixed。
现实中,为了不影响原来的toFixed,你自己也可以这样加原型方法。
来测试一下:
console.log(1.265.toReFixed(2))
console.log(12.225.toReFixed(2))
console.log(123.355.toReFixed(2))
console.log((5555555.555.toReFixed(2)+"").replace(/(\d)(?=(\d{3})+(?!\d))/g, "$1,"))
输出结果(跟人想的一样了):
2.对金额格式的扩展
①如果做的项目页面比较多、涉及金额的内容也比较多,可以另外写金额格式化的方法
// 金额格式化
export function priceFormat(price, decimalsLength = 2) {
if (!price || /^[-]?[0-9,]+([0-9.]+){0,1}$/.test(price.toString()) == false) {
//传入值为空或者有非法值(数字和逗号之外的值)都返回0
return 0;
}
let myPrice = Number(
Number(price.toString().replace(",", "")).toReFixed(decimalsLength)).toLocaleString();
const nums = myPrice.split(".");
if (nums[1]) {
if (nums[1].length === 1) {
return myPrice + "0";
}
return myPrice;
} else {
return myPrice + ".00";
}
}
②有时候,会在输入框内输入有关金额,这时候也要做格式转换
// 金额格式化 (可输入)
export function priceFormatEdit(price, decimalsLength = 2) {
if (!price || /^[-]?[0-9,]+([0-9.]+){0,1}$/.test(price.toString()) == false) {
//传入值为空或者有非法值(数字和逗号之外的值)都返回0
return "";
}
let priceNum = price.toString().replace(/[,]/g, "");
let myPrice = Number(
Number(priceNum).toReFixed(decimalsLength)
).toLocaleString();
const nums = price.toString().split(".");
if (nums[1] && nums[1].length == 1 && nums[1][0] == "0") {
return myPrice + ".0";
}
if (nums[1] && nums[1].length == 2 && nums[1] == "00") {
return myPrice + ".00";
}
if (
nums[1] && nums[1].length == 2 && nums[1][0] != "0" && nums[1][1] == "0"
) {
return myPrice + "0";
}
return myPrice;
}
③有转成金额格式,就有去掉金额格式,因为前端虽然要显示金额格式,但是后端不需要啊(ˉ▽ˉ;)
//去除金额格式
export function resetPriceFormat(price) {
var patt = /[^\d\.-]/g;
var Result = patt.test(price);
if (Result) {
return price ? price.replace(/[^\d\.-]/g, "") : 0;
} else {
return price;
}
}
碎碎念
一只没有大志、只想摸鱼、脑子还不太好使的菜狗的日常记录,有错欢迎评论指出,其他勿扰( ̄︶ ̄*))
有关参考:
1.正则表达式:
2.Js toFixed()四舍五入BUG的解决方法: