この解答例はChatGPTによって生成されています,正しいかは自己判断で。 皆の投稿からも解答例が見つかるかもしれませんよ。
BFE.devでのAI解答例 - JavaScript コーディング問題
127. BigDecimal 引き算
解法:
BigInt の場合と同様に、桁上がりの扱いが厄介な問題です。以下の手順に従って実装することができます。
- 符号を正規化し、引き算対象の二つの文字列の整数部分と小数部分を抽出する。
- 二つの小数部分を桁が合うように調整する。
- 二つの整数部分を末尾から順に引き算し、桁上がりを考慮する。
- 桁上がりがあった場合、繰り上がりがなくなるまで繰り返す。
- 符号、整数部分、小数部分を結合して、最終的な結果を作成する。
- 後続ゼロを取り除く。
以下は実装例です。
function subtract(s1, s2) { const [sign1, intStr1, decimal1] = normalize(s1) const [sign2, intStr2, decimal2] = normalize(s2) let intRes = '' let decRes = '' if (compareAbs(s1, s2) === -1) { // s2 > s1 [sign1, sign2] = [sign2, sign1] ;[intStr1, intStr2] = [intStr2, intStr1] ;[decimal1, decimal2] = [decimal2, decimal1] } let borrow = 0 let i = intStr1.length - 1 let j = intStr2.length - 1 while (i >= 0 || j >= 0) { const num1 = i >= 0 ? Number(intStr1[i]) : 0 const num2 = j >= 0 ? Number(intStr2[j]) : 0 let diff = num1 - num2 - borrow if (diff < 0) { diff += 10 borrow = 1 } else { borrow = 0 } intRes = `${diff}${intRes}` i-- j-- } // Trim leading zeros intRes = intRes.replace(/^0+/, '') const maxLenDec = Math.max(decimal1.length, decimal2.length) let d1 = decimal1.padEnd(maxLenDec, '0') let d2 = decimal2.padEnd(maxLenDec, '0') for (let i = maxLenDec - 1; i >= 0; i--) { let diff = Number(d1[i]) - Number(d2[i]) - borrow if (diff < 0) { diff += 10 borrow = 1 } else { borrow = 0 } decRes = `${diff}${decRes}` } if (borrow === 1) { intRes = subtract(`1${intRes}`, '1') } const resSign = sign1 === '+' ? '' : '-' let res = `${intRes}${decRes ? `.${decRes}` : ''}` res = trimTrailingZeros(res) return resSign + res}function normalize(numStr) { let sign = '' if (numStr[0] === '-' || numStr[0] === '+') { sign = numStr[0] numStr = numStr.slice(1) } let [intStr, decimal] = numStr.split('.') intStr = intStr || '0' decimal = decimal || '' return [sign, intStr, decimal]}function trimTrailingZeros(numStr) { return numStr.replace(/\.?0+$/, '')}function compareAbs(numStr1, numStr2) { const [_, intStr1, decimal1] = normalize(numStr1) const [__, intStr2, decimal2] = normalize(numStr2) if (intStr1.length !== intStr2.length) { return intStr1.length - intStr2.length } for (let i = 0; i < intStr1.length; i++) { const diff = Number(intStr1[i]) - Number(intStr2[i]) if (diff !== 0) { return diff } } if (decimal1.length !== decimal2.length) { return decimal1.length - decimal2.length } for (let i = 0; i < decimal1.length; i++) { const diff = Number(decimal1[i]) - Number(decimal2[i]) if (diff !== 0) { return diff } } return 0}