UNPKG

true-math

Version:

True Math - math library for numbers of arbitrary length

94 lines (64 loc) 2.5 kB
import {checkNumsValue, ifValidArray, isInfinite, isNaNum} from '../checkers/checkers.js'; import {makeNumsSameLength, normalizeNumber} from '../helpers/helpers.js'; import {compareUnsafe} from "./compare.js"; import {absUnsafe} from "./abs.js"; import {signUnsafe} from "../helpers/sign.js"; import isPositiveInfinite from "../checkers/specificValue/isPositiveInfinite.js"; import isNegativeInfinite from "../checkers/specificValue/isNegativeInfinite.js"; function sumDigits(digit1, digit2, sum, memory, multiplier) { let result = memory + digit1 + multiplier * digit2; memory = 0; if (result >= 10 || result < 0) { result += multiplier * -10; memory = multiplier; } sum = result + sum; return [sum, memory]; } export function sum2nums(num1, num2) { let [absNum1, absNum2, decimalPartLength] = makeNumsSameLength(absUnsafe(num1), absUnsafe(num2)); let needMinus = false; let sum = ''; const [num1Sign, num2Sign] = [signUnsafe(num1), signUnsafe(num2)]; const [num1IsNegative, num2IsNegative] = [num1Sign === -1, num2Sign === -1]; const isSecondBigger = compareUnsafe(absNum1, absNum2) === -1; let multiplier = num1Sign * num2Sign || num1Sign || num2Sign; if (multiplier === -1 && isSecondBigger) { [absNum1, absNum2] = [absNum2, absNum1]; } if (num1IsNegative && (num2IsNegative || !isSecondBigger) || num2IsNegative && isSecondBigger) { needMinus = true; } let memory = 0; for (let digit = absNum1.length - 1; digit >= absNum1.length - decimalPartLength; --digit) { [sum, memory] = sumDigits((+absNum1[digit]), (+absNum2[digit]), sum, memory, multiplier); } let integerBeginning = absNum1.length - decimalPartLength - 1; if (decimalPartLength !== 0) { sum = '.' + sum; --integerBeginning; } for (let digit = integerBeginning; digit >= 0; --digit) { [sum, memory] = sumDigits((+absNum1[digit]), (+absNum2[digit]), sum, memory, multiplier); } if (memory === 1) sum = '1' + sum; sum = normalizeNumber(sum); if (needMinus && sum !== '0') sum = '-' + sum; return sum; } export function sumUnsafe(nums) { if (nums.length === 0) return '0'; if (nums.length === 1) return nums[0]; let sum = nums[0]; for (let i = 1; i < nums.length; ++i) { sum = sum2nums(sum, nums[i]); } return sum; } export default function sum(nums) { ifValidArray(nums); nums = nums.map(num => normalizeNumber(num)); const {hasSpecificValue, returnValue} = checkNumsValue(nums, '+'); if (hasSpecificValue) return returnValue; return sumUnsafe(nums); }