javascriptstringalgorithmmathbigint

Multiply big numbers as a string question not using BitInt for codewars but like 4-6 random tests out of like 100 are missing 1 digit


I'm still learning JavaScript so the code is probably messy but this is my function so far. This function is supposed to multiply the shorter number with the larger number digit by digit, padStart them with '0' and put them in an array to be mapped through to add the digits and make them into a string.

function multiply(a, b) {
  let remCont = 0
  let newNum = ''
  let total = 0
  let padStartNum = 0
  let newArr = []
  let newNumZeros = ''


  if((a.length <= 1 && a[0] === '0')||(b.length <= 1 && b[0] === '0')) {
    return '0'
  }

  if(a.length >= b.length) {
    multiplyNums(a,b)
  } else {
    multiplyNums(b,a)
  }

  function multiplyNums(num1,num2) {
    for(let i = num2.length -1;i >= 0;i--) {
      newNum = ''
      remCont = 0
      for(let x = num1.length - 1;x >= 0; x--) {
          total = parseInt(num1[x])*parseInt(num2[i])
          if(remCont > 0) {
            total += remCont
          }
          remCont = 0
          let strTotal = total.toString()
          if(total >= 10 && strTotal[1] === '0') {
            remCont = parseInt(strTotal[0])
            newNum += '0'
          } else if (total >= 10) {
            remCont = parseInt(strTotal[0])
            newNum += strTotal[1]
          } else {
            newNum += strTotal[0]
          }
        }
        if(remCont > 0) {
        newNum += remCont.toString()
        }
        newNumZeros = newNum.padStart(newNum.length+padStartNum,'0')
        padStartNum++
        finalNum = newNumZeros.split('').reverse().join('')
        newArr.push(finalNum)
      }
    }

    let addTotal = ''
    let remCont2
    let total2
    
    newArr.map(a=>addPad(a))
    function addPad(num) {
      if(addTotal.length >= num.length) {
        padB = num.padStart(addTotal.length,'0')
        addSum(addTotal,padB)
      } else {
        padA = addTotal.padStart(num.length,'0')
        addSum(num,padA)
      }
    }
    
    // let testCaseParsed = 0

    // newArr.map(b=>testCase(b.slice(b.length-3)))
    // function testCase(num) {
    //     testCaseParsed += parseInt(num)
    // }
    // let finalThree = testCaseParsed.toString()

    function addSum(num1,num2) {
      addTotal = ''
      for(let i = num1.length - 1;i >= 0;i--) {
      total2 = 0
      if(num2[i] === '0') {
        total2 = parseInt(num1[i])
      } else {
        total2 = parseInt(num1[i])+parseInt(num2[i])
      }
      if(remCont2 > 0) {
        total2++
      }
      remCont2 = 0
      if(total2 >= 10) {
        remCont2++
        total2 -= 10
      }
      addTotal += total2.toString() 
    }
    if(remCont2 > 0) {
      let lastRem = 1
      addTotal += lastRem.toString()
    }
    addTotal = addTotal.split('').reverse().join('').replace(/^0+/, "")
}
  // if(addTotal.length >= 7) {
  //   let result = addTotal.slice(0,addTotal.length-3) + finalThree
  //   return result
  // }
    return addTotal
}

// console.log(multiply("2" ,"0"))
// console.log(multiply("51", "23"))
// console.log(multiply("9", "9"))
// console.log(multiply("311", "692"))
// console.log(multiply("1009", "03"))
// console.log(multiply("5009", "932"))
// Supposed to be: 4668388
// console.log(multiply("210", "613"))
// console.log(multiply("1020303004875647366210", "2774537626200857473632627613"))
// Supposed to be: "2830869077153280552556547081187254342445169156730"
// console.log(multiply("9007199254740991", "9007199254740991"))
// Supposed to be: "81129638414606663681390495662081"
// console.log(multiply("58608473622772837728372827", "7586374672263726736374"))
// Supposed to be: "444625839871840560024489175424316205566214109298"

I've tried this as is and the issue that I get is that the number at the end will be off by 1 so I tried just slicing the result till like the last 3 digits and adding in the last 3 numbers of the addition back in and it worked but then I ran into an issue where for other really big numbers the fourth to the last digit was missing and yet for others it worked like 6 or so failed out of like 100. I tried scrapping that idea and went back to the original code here but I'm confused where this difference of 1 comes from. I've also commented out what I've been trying to do to fix the last digits being different since that didn't work either.


Solution

  • The problem is that remCont2 may have a nonzero value when addSum returns, and this value creeps into the next call of addSum.

    These kinds of problems will never occur if you take the habit of declaring all your variables in the scope where they are needed:

    Some other remarks: