文字列と数値の演算が異なる理由
やりたかったこと・やったこと
・文字列の数値同士で引き算がしたかった
・文字列→数値型に変換して引き算を行った
1の補数を取得するプログラム*1
function oneComplement(bits){ let n = bits.length; let oneComplement = ""; for(let i=0; i < n; i++) { oneComplement+="1"; } console.log(oneComplement); let one = String(Number(oneComplement) - bits); console.log(one); return one.length == n ? one : one.padStart(n, '0'); }
入力値
"0011000101000000111101011111100001001011000001011010101001010110110101101001000101011010011010011100100100000101110"
結果
1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 1.100111010111111e+114*2
→桁数が大きすぎて計算ができていない。 →数値の引き算で期待する結果が得られなかった。
原因
端的にいえば、文字列と数値ではデータ型が異なるため、というのが理由。
コンピュータは数値を2進数で表現するが、有限のビット数しか使えないため*3、数値の精度に制限があるということを抑えておきたい。特に、浮動小数点数の場合、小数点以下の桁数が制限されるため、計算結果が正確に表現されないことがあるとのこと。これが、数値の引き算で期待する結果が得られない場合がある理由。
今回でいえば、入力値の桁数が数値として扱える有限ビット数の桁数をオーバーしていたのが原因。