UNPKG

luxi-record-utils

Version:
82 lines 4.43 kB
/* ** 超长数字相加 ** 只允许输入字符串,因为数字长度问题会把一些超大数字转化为科学计数法 ** 例如: 0.000000000000003 ==> '3e-15' */ function numberAdd(a: string, b: string): string { if (!a || !b) throw new Error('Please enter two strings composed of numbers') const isReduce = (Number(a) > 0 && Number(b) < 0 || Number(a) < 0 && Number(b) > 0) ? true : false const isNegative = Number(a) < 0 && Number(b) < 0 ? true : false let resulet = '', carry = 0 if (isReduce) { const numberOne = Number(a), numberTwo = Number(b) const absNumberOne = a.replace('-', ''), absNumberTwo = b.replace('-', '') const hasMinusSign = (Math.abs(numberOne) > Math.abs(numberTwo) && numberOne < 0) || (Math.abs(numberTwo) > Math.abs(numberOne) && numberTwo < 0) ? true : false const length = absNumberOne.length const big = Math.abs(numberOne) > Math.abs(numberTwo) ? absNumberOne : absNumberTwo const small = Math.abs(numberOne) < Math.abs(numberTwo) ? absNumberOne : absNumberTwo for (let i = length - 1; i >= 0; i--) { const numberA = Number(big[i]), numberB = Number(small[i]) const tmp = numberA - numberB - carry if (tmp < 0) { carry = 1 resulet = tmp + 10 + resulet } else { carry = 0 resulet = tmp + resulet } } resulet = hasMinusSign ? `-${resulet}` : resulet } else { const stringOne = isNegative ? a.replace('-', '') : a const stringTwo = isNegative ? b.replace('-', '') : b const length = stringOne.length for (let i = length - 1; i >= 0; i--) { const numberA = Number(stringOne[i]), numberB = Number(stringTwo[i]) const tmp = numberA + numberB + carry carry = Math.floor(tmp / 10) resulet = tmp % 10 + resulet } if (carry) resulet = carry + resulet resulet = isNegative ? `-${resulet}` : resulet } return resulet } export default function largeNumberAdd(num1: string, num2: string): string { let stringOne = String(num1), stringTwo = String(num2) const reg = /^(-?\d+)(\.\d+)?$/ // /^-?\d+$/ 整数 /^0+$/ 全零 if (!reg.test(stringOne) || !reg.test(stringTwo)) { throw new Error('Please enter a string composed of numbers') } const stringOneLess = Number(stringOne) < 0 ? true : false const stringTwoLess = Number(stringTwo) < 0 ? true : false const isFloat = stringOne.includes('.') || stringTwo.includes('.') let pointIndex: number | null = null if (isFloat) { let stringOneFloat = stringOne.split('.')[1] || '' let stringTwoFloat = stringTwo.split('.')[1] || '' pointIndex = Math.max(stringOneFloat.length, stringTwoFloat.length) stringOneFloat = stringOneFloat.padEnd(pointIndex, '0') stringTwoFloat = stringTwoFloat.padEnd(pointIndex, '0') pointIndex = Number(`-${pointIndex}`) let stringOneInteger = stringOne.replace('-', '').split('.')[0] let stringTwoInteger = stringTwo.replace('-', '').split('.')[0] const maxLength = Math.max(stringOneInteger.length, stringTwoInteger.length) stringOneInteger = stringOneInteger.padStart(maxLength, '0') stringTwoInteger = stringTwoInteger.padStart(maxLength, '0') stringOne = stringOneLess ? `-${stringOneInteger}${stringOneFloat}` : stringOneInteger + stringOneFloat stringTwo = stringTwoLess ? `-${stringTwoInteger}${stringTwoFloat}` : stringTwoInteger + stringTwoFloat } else { let stringOneInteger = stringOne.replace('-', '') let stringTwoInteger = stringTwo.replace('-', '') const maxLength = Math.max(stringOneInteger.length, stringTwoInteger.length) stringOneInteger = stringOneInteger.padStart(maxLength, '0') stringTwoInteger = stringTwoInteger.padStart(maxLength, '0') stringOne = stringOneLess ? `-${stringOneInteger}` : stringOneInteger stringTwo = stringTwoLess ? `-${stringTwoInteger}` : stringTwoInteger } console.log(stringOne, stringTwo) const result = numberAdd(stringOne, stringTwo) if (pointIndex) return `${result.slice(0, pointIndex)}.${result.slice(pointIndex)}` return result }