方案1和方案2都是有效的
=====注意参数一定要是数字 而不能是字符串 否则会计算错误 =====
情景: 在计算浮点数时候,出现多余小数。
例如: 1.11 + 1 = 2.1100000000000003
为什么计算小数会出现误差?
浮点数值的最高进度是17位小数,但在进行运算的时候其精确度却远远不如整数;整数在进行运算的时候都会转成10进制; 而Java和JavaScript中计算小数运算时,都会先将十进制的小数换算到对应的二进制,一部分小数并不能完整的换算为二进制,这里就出现了第一次的误差。待小数都换算为二进制后,再进行二进制间的运算,得到二进制结果。然后再将二进制结果换算为十进制,这里通常会出现第二次的误差。
方案1:简单的js加法和减法:
//加法
Math.round((parseFloat(num1) + parseFloat(num2))*100)/100
//减法
Math.round((parseFloat(num1) - parseFloat(num2))*100)/100
方案2:复杂的加减乘除运算封装:
以下代码可以直接复制使用
有效的话请点赞评论下,让更多的朋友能够看到解决问题!
<template>
<div style="padding:20px;">
<div><span>1.11 + 1 = {{ 1.11 + 1 }}</span> <span>-----处理浮点计算:{{ addNum }}</span></div>
<div><span>1.11 - 1 = {{ 1.11 - 1 }}</span> <span>-----处理浮点计算:{{ subNum }}</span></div>
<div><span>1.11 * 100= {{ 1.11 * 100 }}</span> <span>-----处理浮点计算:{{ mulNum }}</span></div>
<div><span>0.11 / 0.1 = {{ 0.11 / 0.1 }}</span> <span>-----处理浮点计算:{{ divNum }}</span></div>
<div><span> (((1.11 + 1) - 1) * 100) / 0.1 = {{ (((1.11 + 1) - 1) * 100) / 0.1 }}</span> <span>-----处理浮点计算:{{ lastNum }}</span></div>
</div>
</template>
<script>
export default {
data () {
return {
addNum: 0,
subNum: 0,
mulNum: 0,
divNum: 0,
lastNum: 0
}
},
created () {
this.getNum()
},
methods: {
getNum () {
console.log(1.11 + 1)
console.log(1.11 - 1)
console.log(1.11 * 100)
console.log(0.11 / 0.1)
console.log((((1.11 + 1) - 1) * 100) / 0.1)
// ================注意参数一定要是数字 而不能是字符串 否则会计算错误 ====================
this.addNum = this.floatObj().add(1.11, 1)// 加法
this.subNum = this.floatObj().subtract(1.11, 1)// 减法
this.mulNum = this.floatObj().multiply(1.11, 100)// 乘法
this.divNum = this.floatObj().divide(0.11, 0.1)// 除法
this.lastNum = this.floatObj().divide(this.floatObj().multiply(this.floatObj().subtract(this.floatObj().add(1.11, 1), 1), 100), 0.1)// 混合运算
},
/** * 封装了加减乘除四种计算方法 **
// ================注意参数一定要是数字 而不能是字符串 否则会计算错误 ====================
* add / subtract / multiply /divide
* this.floatObj().add(1.11, 1)// 加法
* this.floatObj().subtract(1.11, 1)// 减法
* this.floatObj().multiply(1.11, 100)// 乘法
* this.floatObj().divide(0.11, 0.1)// 除法
*/
floatObj () {
// 判断obj是否为一个整数
function isInteger (obj) {
return Math.floor(obj) === obj
}
/*
* 将一个浮点数转成整数,返回整数和倍数。如 3.14 >> 314,倍数是 100
* @param floatNum {number} 小数
* @return {object}
* {times:100, num: 314}
*/
function toInteger (floatNum) {
var ret = { times: 1, num: 0 }
if (isInteger(floatNum)) {
ret.num = floatNum
return ret
}
var strfi = floatNum + ''
var dotPos = strfi.indexOf('.')
var len = strfi.substr(dotPos + 1).length
var times = Math.pow(10, len)
var intNum = Number(floatNum.toString().replace('.', ''))
ret.times = times
ret.num = intNum
return ret
}
/*
* 核心方法,实现加减乘除运算,确保不丢失精度
* 思路:把小数放大为整数(乘),进行算术运算,再缩小为小数(除)
*
* @param a {number} 运算数1
* @param b {number} 运算数2
* @param op {string} 运算类型,有加减乘除(add/subtract/multiply/divide)
*
*/
function operation (a, b, op) {
var o1 = toInteger(a)
var o2 = toInteger(b)
var n1 = o1.num
var n2 = o2.num
var t1 = o1.times
var t2 = o2.times
var max = t1 > t2 ? t1 : t2
var result = null
switch (op) {
case 'add':
if (t1 === t2) { // 两个小数位数相同
result = n1 + n2
} else if (t1 > t2) { // o1 小数位 大于 o2
result = n1 + n2 * (t1 / t2)
} else { // o1 小数位 小于 o2
result = n1 * (t2 / t1) + n2
}
return result / max
case 'subtract':
if (t1 === t2) {
result = n1 - n2
} else if (t1 > t2) {
result = n1 - n2 * (t1 / t2)
} else {
result = n1 * (t2 / t1) - n2
}
return result / max
case 'multiply':
result = (n1 * n2) / (t1 * t2)
return result
case 'divide':
result = (n1 / n2) * (t2 / t1)
return result
}
}
// 加减乘除的四个接口
function add (a, b) { // 加法
return operation(a, b, 'add')
}
function subtract (a, b) { // 减法
return operation(a, b, 'subtract')
}
function multiply (a, b) { // 乘法
return operation(a, b, 'multiply')
}
function divide (a, b) { // 除法
return operation(a, b, 'divide')
}
return {
add: add,
subtract: subtract,
multiply: multiply,
divide: divide
}
}
}
}
</script>
<style>
</style>