温州 公司 网站,深圳网站建设网站,医疗器械龙头股,wordpress主题xiu项目场景#xff1a;
商城类项目中大多需要金额计算#xff0c;我们知道计算机编程语言里浮点数计算会存在精度丢失问题#xff08;或称舍入误差#xff09;#xff0c;其根本原因是二进制和实现位数限制有些数无法有限表示
以下是十进制小数对应的二进制表示#xff1…项目场景
商城类项目中大多需要金额计算我们知道计算机编程语言里浮点数计算会存在精度丢失问题或称舍入误差其根本原因是二进制和实现位数限制有些数无法有限表示
以下是十进制小数对应的二进制表示 0.1 0.0001 1001 1001 1001…1001无限循环 0.2 0.0011 0011 0011 0011…0011无限循环 计算机里每种数据类型的存储是一个有限宽度比如 JavaScript 使用 64 位存储数字类型因此超出的会舍去。舍去的部分就是精度丢失的部分。 如果直接加减乘除 0.1 0.2 0.30000000000000004 多了 0.00000000000004 0.2 0.4 0.6000000000000001 多了 0.0000000000001 19.9 * 100 1989.9999999999998 少了 0.0000000000002 所以要精确计算需要进行处理实现加减乘除运算确保不丢失精度
解决方案
/*** 判断是否为一个整数* param {object} obj 字符串* return {boolean} true/false*/
export function isInteger(obj) {return Math.floor(obj) obj;
}/*** 将一个浮点数转成整数返回整数和倍数。如 3.14 314倍数是 100* param {object} floatNum 小数* return {object} {times:100, num: 314}*/
export function toInteger(floatNum) {var ret { times: 1, num: 0 }var isNegative floatNum 0if (isInteger(floatNum)) {ret.num floatNumreturn ret}var strfi floatNum var dotPos strfi.indexOf(.)var len strfi.substr(dotPos 1).lengthvar times Math.pow(10, len)var intNum parseInt(Math.abs(floatNum) * times 0.5, 10)ret.times timesif (isNegative) {intNum -intNum}ret.num intNumreturn ret
}/*** 浮点型数字运算精度丢失修复* param {object} num 小数* param {number} s 小数位数* return {object} s位小数*/
export function toFixed(num, s) {var times Math.pow(10, s);var des num * times 0.5;des (parseInt(des, 10) / times) ;var pos_decimal des.indexOf(.);if (pos_decimal 0) {while (des.length pos_decimal s) {des 0;}}return des;
}/*** 浮点型数字运算精度丢失修复* 核心方法实现加减乘除运算确保不丢失精度* 思路把小数放大为整数乘进行算术运算再缩小为小数除* param a {number} 运算数1* param b {number} 运算数2* param dig {number} 精度保留的小数点数比如 2, 即保留为两位小数* param op {string} 运算类型有加减乘除add/subtract/multiply/divide* return {object} dig位小数*/
function operation(a, b, dig, op) {var o1 toInteger(a)var o2 toInteger(b)var n1 o1.numvar n2 o2.numvar t1 o1.timesvar t2 o2.timesvar max t1 t2 ? t1 : t2var result nullswitch (op) {case add:if (t1 t2) { // 两个小数位数相同result n1 n2} else if (t1 t2) { // o1 小数位 大于 o2result n1 n2 * (t1 / t2)} else { // o1 小数位 小于 o2result n1 * (t2 / t1) n2}return toFixed(result / max, dig)case subtract:if (t1 t2) {result n1 - n2} else if (t1 t2) {result n1 - n2 * (t1 / t2)} else {result n1 * (t2 / t1) - n2}return toFixed(result / max, dig)case multiply:result (n1 * n2) / (t1 * t2)return toFixed(result, dig)case divide:if (n2 0)result 0elseresult (n1 / n2) * (t2 / t1)return toFixed(result, dig)}
}/*** 加法* param a {number} 运算数1* param b {number} 运算数2* return {object} s位小数*/
export function add(a, b, s) {return operation(a, b, (s | 2), add)
}/*** 减法* param a {number} 运算数1* param b {number} 运算数2* return {object} s位小数*/
export function subtract(a, b, s) {return operation(a, b, (s | 2), subtract)
}/*** 乘法* param a {number} 运算数1* param b {number} 运算数2* return {object} s位小数*/
export function multiply(a, b, s) {return operation(a, b, (s | 2), multiply)
}/*** 除法* param a {number} 运算数1* param b {number} 运算数2* return {object} s位小数*/
export function divide(a, b, s) {return operation(a, b, (s | 2), divide)
}
上面的为math.js文件封装到这里面然后引用 vue中引用使用方法 main.js: import * as math from ‘./utils/math’//引入js Vue.prototype.math math
使用 this.math.add(this.numberCases, this.Number)
标签中引用
{{math.multiply(item.Discount, item.Num)}}