js的 parseFloat 精度有问题。
经测试,当长度超过16位就有可能失真
toFixed(2) 用来约束末尾有两位小数部分
var x = "1234567890123456789";
var f = parseFloat(x).toFixed(2);
alert(f);// 1234567890123456700.00 已经失真
对小数部分的最后一位进行四舍五入
var f = Math.round(f*100)/100;
需求:一个文本框,
输入金额(金额整数部分长度为20位,超过使用parseFloat的16位的失真临界点)
对金额进行四舍五入,保留两位小数。
做法:把输入的文本根据小数点位置平均截为两个float,命名为A、B。
B需要进行四舍五入操作。
四舍五入操作需要首先把B 乘以 100再四舍五入再除以100,
必须保证乘以100后不失真。
也就是B的长度为 16-2 = 14(最保险的是长度为13)
由于AB的整数长度相同,所以输入的最长为28(最保险的长度为26,满足需求的20)
如下:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<TITLE> New Document </TITLE>
<META NAME="Generator" CONTENT="EditPlus">
<META NAME="Author" CONTENT="">
<META NAME="Keywords" CONTENT="">
<META NAME="Description" CONTENT="">
<script>
function doCheck() {
var x = document.getElementById("changeData").value;
var i = x.indexOf('.');
var splitIndex = 0;
if(i <0){
splitIndex = x.length/2;
}else{
splitIndex = i/2;
}
var x1 = x.substring(0,splitIndex);
var x2 = x.substring(splitIndex,x.length);
var f1 = parseFloat(x1);
var f2 = parseFloat(x2).toFixed(2);
f2 = parseFloat(Math.round(f2*100)/100).toFixed(2);
var ret = "";
if(("" + f2).indexOf('.') > x2.indexOf('.')){
ret = "" + (f1 + 1) + f2.substring(1, f2.length);
}else{
ret = "" + f1 + f2;
}
document.getElementById("tf1").value = x;
document.getElementById("tf2").value = ret;
return f1 + f2;
}
</script>
</HEAD>
<BODY>
<input type='textfield' οnchange='doCheck()' id='changeData' size='100'/><br />
<input type='textfield' id='tf1' size='100'/><br />
<input type='textfield' id='tf2' size='100'/><br />
</BODY>
</HTML>