在javascript中进行运算的时候经常会出现浮点数的问题,导致运算结果不准确
比如:0.1 + 0.2 = 0.30000000000000004
完整demo及解决方案如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>demo</title>
<style>
.num-tags,
.total-tag {
text-align: center;
}
i {
font-style: normal;
}
#totalTag {
color: red;
}
</style>
</head>
<body>
<div class="num-tags">
<label for="moneys1">数值1:</label>
<input type="text" class="moneys" value="" onkeyup="checkInput(this)" onblur="checkNum(this)" />
<label for="moneys2">数值2:</label>
<input type="text" class="moneys" value="" onkeyup="checkInput(this)" onblur="checkNum(this)" />
<button type="button" id="calculates">求和</button>
</div>
<div class="total-tag"><i>合计:</i><span id="totalTag"></span></div>
<script>
document.getElementById('calculates').onclick = function () {
var countSum = 0
var nums = document.querySelectorAll('.moneys')
for (var i = nums.length; i--; ) {
// 在两值相加时,调用升幂降幂函数
countSum = formatNum((countSum += parseFloat(nums[i].value)), 10)
}
// 为确保计算精度,在赋值之前调用保留两位小数的函数
document.getElementById('totalTag').innerText = toDecimal2(countSum)
}
function checkInput(_this) {
if (_this.value != '' && _this.value.substr(0, 1) == '.') {
_this.value = 0
}
if (_this.value == '') {
_this.value = 0
}
_this.value = _this.value.replace(/^0*(0\.|[1-9])/, '$1') // 禁止粘贴
_this.value = _this.value.replace(/[^\d.]/g, '0.00') // 禁止输入非数字
_this.value = _this.value.replace(/\.{2,}/g, '.') // 只保留第一个. 清除多余的
_this.value = _this.value.replace('.', '$#$').replace(/\./g, '').replace('$#$', '.')
_this.value = _this.value.replace(/^(\-)*(\d+)\.(\d\d).*$/, '$1$2.$3') // 只能输入两个小数
if (_this.value.indexOf('.') < 0 && _this.value != '') {
// 以上已经过滤,此处控制的是如果没有小数点,首位不能为类似于 01、02的金额
if (_this.value.substr(0, 1) == '0' && _this.value.length == 2) {
_this.value = _this.value.substr(1, _this.value.length)
}
}
if (!_this.value) {
_this.value = 0
}
}
function checkNum(_this) {
// 失去焦点的时候判断 如果最后一位是 . 末尾补0
_this.value.endsWith('.') ? (_this.value += '0') : _this.value
}
// 保留两位小数
function toDecimal2(x) {
var f = parseFloat(x)
if (isNaN(f)) {
return false
}
var f = Math.round(x * 100) / 100
var s = f.toString()
var rs = s.indexOf('.')
if (rs < 0) {
rs = s.length
s += '.'
}
while (s.length <= rs + 2) {
s += '0'
}
return s
}
// 把需要计算的数字乘以 10 的 n 次幂,换算成计算机能够精确识别的整数,然后再除以 10 的 n 次幂
function formatNum(f, digit) {
var m = Math.pow(10, digit)
return parseInt(f * m, 10) / m
}
</script>
</body>
</html>