AI solution for JavaScript Coding Question on BFE.dev
127. BigDecimal subtraction
There are multiple approaches to solve this problem, but one common method is to mimic the process of manual subtraction we learned in elementary school. Specifically, we can start from the rightmost digit of the two numbers, subtract the corresponding digits and handle the borrow if there is any. We can repeat this process for all digits until reaching the leftmost digit. Here is one possible implementation:
function subtract(a, b) { const [aInt, aFrac] = a.split('.') const [bInt, bFrac] = b.split('.') const maxFrac = Math.max( aFrac ? aFrac.length : 0, bFrac ? bFrac.length : 0, ) // pad trailing zeroes to make both fractions have the same length const paddedA = aFrac ? aFrac.padEnd(maxFrac, '0') : '' const paddedB = bFrac ? bFrac.padEnd(maxFrac, '0') : '' let borrow = 0 let result = '' let i = aInt.length - 1 let j = bInt.length - 1 let k = maxFrac - 1 while (i >= 0 || j >= 0 || k >= 0) { const aDigit = i >= 0 ? aInt.charCodeAt(i) - 48 : 0 const bDigit = j >= 0 ? bInt.charCodeAt(j) - 48 : 0 const fracDigitA = k >= 0 ? paddedA.charCodeAt(k) - 48 : 0 const fracDigitB = k >= 0 ? paddedB.charCodeAt(k) - 48 : 0 const digitDiff = (aDigit - bDigit - borrow + 10) % 10 const fracDiff = (fracDigitA - fracDigitB - borrow + 10) % 10 result = digitDiff + result borrow = aDigit < bDigit + borrow ? 1 : 0 borrow = fracDigitA < fracDigitB + borrow ? 1 : borrow i-- j-- k-- } // remove leading zeroes result = result.replace(/^0*/, '') // handle negative numbers if (result.charAt(0) === '-') { let i = 1 while (result.charAt(i) === '0') { i++ } result = result.slice(0, i) + result.slice(i + 1) } // handle zero result if (result === '') { return '0' } if (a.charAt(0) === '-' && b.charAt(0) !== '-') { return '-' + result } if (a.charAt(0) !== '-' && b.charAt(0) === '-') { return result } if (a.charAt(0) === '-' && b.charAt(0) === '-') { return '-' + result } return result}
The function first separates the integer part and fractional part of a
and b
, and figures out the maximum length of the two fractions. It then pads trailing zeroes to make both fractions have the same length, which simplifies the subtraction logic.
The function then sets up a loop that goes from right to left of the integer parts and fractions (if any) of a
and b
. Inside the loop, it extracts the corresponding digits (or zeroes if the digits don't exist), performs the subtraction, handles the borrow, and updates the result string.
After the loop, the function removes leading zeroes from the result (if any), handles negative numbers (by removing the leading zero in -0
or removing the negative sign if there is no other non-zero digit), and returns the result with proper sign (negative if only a
is negative, positive if only b
is negative, and the same as the result if both a
and b
have the same sign).
Note that this implementation assumes that both a
and b
are valid decimal numbers (with optional sign, integer part and fractional part separated by a dot). If the inputs can be malformed, the function should check their validity first.