解决浮点数进行加减乘除之后精度丢失问题,保留固定小数方法

一、正则判断合法数字

function isLegalNum(num) {

  let flag = /^((\d(\.\d+)?)|([1-9]\d*(\.\d+)?))$/g.test(num)

  if (!flag) {

    console.log(`${num}不是合法数字`)

  }

  return flag

}

二、加法

function add(firstNum = 0, secondNum = 0) {

  if (!firstNum || !isLegalNum(firstNum) || !secondNum || !isLegalNum(secondNum)) {

    return secondNum

  } 

  let firstNumStr = firstNum.toString()

  let secondNumStr = secondNum.toString()

  let decimalCount1 = (firstNumStr.split('.')[1] || '').length

  let decimalCount2 = (secondNumStr.split('.')[1] || '').length

  let max = Math.max(decimalCount1, decimalCount2)

  let index = Math.pow(10, max)

  let mul1 = decimalCount1 === max ? 0 : max - decimalCount1

  let mul2 = decimalCount2 === max ? 0 : max - decimalCount2

  let first = firstNumStr.replace('.', '') * Math.pow(10, mul1)

  let second = secondNumStr.replace('.', '') * Math.pow(10, mul2)

  return (first + second) / index

}

三、减法

function sub(firstNum = 0, secondNum = 0) {

  if (!secondNum || !isLegalNum(secondNum) || !firstNum || !isLegalNum(firstNum)) {

    return firstNum

  }

  let firstNumStr = firstNum.toString()

  let secondNumStr = secondNum.toString()

  let decimalCount1 = (firstNumStr.split('.')[1] || '').length

  let decimalCount2 = (secondNumStr.split('.')[1] || '').length

  let max = Math.max(decimalCount1, decimalCount2)

  let index = Math.pow(10, max) 

  let mul1 = decimalCount1 === max ? 1 : max - decimalCount1

  let mul2 = decimalCount2 === max ? 1 : max - decimalCount2

  let first = firstNumStr.replace('.', '') * Math.pow(10, mul1)

  let second = secondNumStr.replace('.', '') * Math.pow(10, mul2)

  return (first - second) / index

}

四、乘法

function multiply(firstNum = 0, secondNum = 0) {

  if (!firstNum || !isLegalNum(firstNum) || !secondNum || !isLegalNum(secondNum)) {

    return 0

  }

  let firstNumStr = firstNum.toString()

  let secondNumStr = secondNum.toString()

  let decimalCount1 = (firstNumStr.split('.')[1] || '').length

  let decimalCount2 = (secondNumStr.split('.')[1] || '').length 

  let decimalCount = decimalCount1 + decimalCount2 

  let index = Math.pow(10, decimalCount)

  let first = firstNumStr.replace('.', '')

  let second = secondNumStr.replace('.', '')

  return (first * second) / index 

}

 

五、除法 

function divide(firstNum = 0, secondNum = 0) {

  if (!firstNum || !isLegalNum(firstNum) || !secondNum || !isLegalNum(secondNum)) { 

    return 0

  }

  let firstNumStr = firstNum.toString()

  let secondNumStr = secondNum.toString()

  let decimalCount1 = (firstNumStr.split('.')[1] || '').length

  let decimalCount2 = (secondNumStr.split('.')[1] || '').length

  let index = Math.pow(10, decimalCount2 - decimalCount1)

  let first = firstNumStr.replace('.', '')

  let second = secondNumStr.replace('.', '')

  return multiply((first / second), index)

}

六、保留固定小数位(四舍五入)

function fixDecimal(num, decimalCount = 2) {

  if (num === 0) {

    return '0' + '.' + '0'.repeat(decimalCount)

  }

  if (!num || !isLegalNum(num)) {

    return num 

  }

  let numStr = num.toString()

  let intStr = numStr.split('.')[0]

  let decimalStr = numStr.split('.')[1] || ''

  let totalCount = decimalStr.length

  if (totalCount === decimalCount) {

    return num

  }

  if (totalCount < decimalCount) {

    return numStr + '0'.repeat(decimalCount - totalCount)

  }

  let part1 = decimalStr.slice(0, decimalCount)

  let part2 = decimalStr.slice(decimalCount, decimalCount + 1)

  let relDecimalStr = part1

  let isPlusOne = false

  if (parseInt(part2) >= 5) {

    let str = (parseInt(part1) + 1).toString()

    isPlusOne = str.length > part1.length

    relDecimalStr = isPlusOne ? str.slice(1) : str

  }

  let relIntStr  = isPlusOne ? (parseInt(intStr) + 1).toString() : intStr

  return relIntStr  + '.' + relDecimalStr

}

六、左侧补零

function leftZero(param, totalLength = 4) {

  return ('0'.repeat(totalLength) + param).slice((param + '').length)

}

 

上一篇:OpenSSL漏洞披露:想法没错 时间不对


下一篇:Java使用for循环打印三位数的水仙花数