方法一:
保留字符串类型,传给后端
方法二:
如果涉及到计算,用以下方法
// 核心思想 在计算前,将数字乘以相同倍数,让他没有小数位,然后再进行计算,然后再除以相同的倍数,恢复原来的小数位
function add(a, b) {
const precisionA = getPrecisionA(a)
const precisionB = getPrecisionB(b)
var multiplier = Math.pow(10, Math.max(precisionA, precisionB))
return (a * multiplier + b * multiplier) / multiplier
}
function getPrecisionA() {
if (num.toString().indexOf('e') !== -1) {
var precision = num.toString().split('e-')[1]
return parseInt(precision, 10)
}
var decimalPart = num.toString().split('.')[1]
return decimalPart ? decimalPart.length : 0
}
以下是完整函数:
/**
* 把递归操作扁平迭代化
* @param {number[]} arr 要操作的数字数组
* @param {function} operation 迭代操作
* @private
*/
function iteratorOperation(arr,operation){
const [num1,num2,...others]=arr;
let res=operation(num1,num2)
other.forEach((num)=>{
res=operation(res,num)
})
return res
}
/**
* 返回小数部分的长度
* @private
* @param {*number} num Input number
*/
function digitLength(num){
// 指数部分通常是用字母 "e" 或 "E" 后跟一个整数表示
const eSplit=num.toString().spilt(/[eE]/);
const len=(eSplit[0].split('.')[1] || '').length - +(eSplit[1] || 0);
return len>0?len:0;
}
/**
* 把小数转成整数,如果是小数则放大成整数
* @private
* @param {*number} num 输入数
*/
function float2Fixed(num){
if(num.toString().indexOf('e')===-1){
return Number(num.toString().replace('.',''))
}
const dLen = digitLength(num);
return dLen > 0 ? strip(Number(num) * Math.pow(10, dLen)) : Number(num);
}
/**
* 把错误的数据转正
* @private
* @example strip(0.09999999999999998)=0.1
*/
function strip(num,precision=15){
// toPrecision将数字转换为具有指定有效数字位数的字符串表示形式
// parseFloat 将字符串转为浮点数
return +parseFloat(Number(num).toPrecision(precision));
}
/**
* 高精度乘法
*/
function times(...nums){
if (nums.length > 2) {
return iteratorOperation(nums, times);
}
const [num1, num2] = nums;
const num1Changed = float2Fixed(num1);
const num2Changed = float2Fixed(num2);
const baseNum = digitLength(num1) + digitLength(num2);
const leftValue=num1Changed * num2Changed
// 并返回底数的指数次幂
return leftValue/ Math.pow(10, baseNum);
}
/**
* 高精度加法
*/
function plus(...nums){
if(nums.length>2){
return iteratorOperation(nums, plus)
}
const [num1,num2]=nums
// 取最大的小数位
// Math.pow 函数计算以 10 为底、指数为两个数字小数部分长度的最大值的幂次方
const baseNum=Math.pow(10,Math.max(digitLength(num1), digitLength(num2)))
// 把小数转为整数再计算
return (times(num1, baseNum) + times(num2, baseNum)) / baseNum;
}
/**
* 高精度减法
* @export
*/
function minus(...nums) {
if (nums.length > 2) {
return iteratorOperation(nums, minus);
}
const [num1, num2] = nums;
const baseNum = Math.pow(10, Math.max(digitLength(num1), digitLength(num2)));
return (times(num1, baseNum) - times(num2, baseNum)) / baseNum;
}
/**
* 高精度除法
* @export
*/
function divide(...nums) {
if (nums.length > 2) {
return iteratorOperation(nums, divide);
}
const [num1, num2] = nums;
const num1Changed = float2Fixed(num1);
const num2Changed = float2Fixed(num2);
checkBoundary(num1Changed);
checkBoundary(num2Changed);
// 重要,这里必须用strip进行修正
return times(num1Changed / num2Changed, strip(Math.pow(10, digitLength(num2) - digitLength(num1))));
}