JavaScript
 Computer >> コンピューター >  >> プログラミング >> JavaScript

JavaScriptで10進数に変換せずに2進数同士を加算する方法

この記事では、JavaScriptを使って2進数の文字列を10進数に変換せずにそのまま加算する関数の実装方法を解説します。大きな数値でも精度の心配なく扱える、実用的なアプローチです。

問題の概要

2つの2進数の文字列 str1str2 を引数として受け取り、それらを加算した結果を返すJavaScript関数を作成します。

ただし、以下の制約があります。

  • 2進数を10進数に変換してから加算することは禁止
  • 結果として返す文字列の先頭に余分な「0」が含まれてはいけない

たとえば、次のような入力が与えられた場合を考えます。

入力:

const str1 = '1101';
const str2 = '10111';

出力:

const output = '100100';

実際、「1101」(13)+「10111」(23)=「100100」(36)となり、正しい結果が得られます。

解決の考え方: 筆算方式のシミュレーション

人間が紙の上で行う筆算と同じ要領で、下の桁から順番に1桁ずつ足し合わせていくのがポイントです。各桁の合計が2以上になったら繰り上がり(carry)を発生させ、次の桁の計算に持ち越します。

具体的な手順は以下の通りです。

  • 両方の文字列を反転させ、最下位桁から処理できるようにする
  • ループの中で対応する桁どうしを加算し、繰り上がりも含めて計算する
  • temp % 2 を現在の桁の値とし、temp > 1 で繰り上がりの有無を判定する
  • 最後に結果文字列の先頭にある不要な「0」を削除する

サンプルコード

以下が実装コードです。

const str1 = '1101';
const str2 = '10111';
const addBinary = (str1 = '', str2 = '') => {
    str1 = str1.split('').reverse();
    str2 = str2.split('').reverse();
    let res = '', temp = 0;

    while (str1.length || str2.length || temp) {
        temp += (~~str1.shift()) + (~~str2.shift());
        let mod = temp % 2;
        res = mod + res;
        temp = temp > 1;
    };
    return (+res) ? res.replace(/^0+/, '') : '0';
};
console.log(addBinary(str1, str2));

出力結果

100100

コードのポイント解説

  • reverse() + shift(): 文字列を配列化して反転することで、先頭(元は末尾)から桁を順に取り出せるようにしています。
  • ~~演算子: undefined0 に変換するテクニックです。片方の文字列が先に尽きた場合でもエラーにならず、安全に加算できます。
  • res.replace(/^0+/, ''): 計算過程で生じた先頭の余分な0を除去し、規定どおりの出力形式を保証します。
  • (+res) ? ... : '0': 両方の入力が「0」の場合など、計算結果が空になるケースにも対応しています。

この手法なら、Number 型の精度限界(約2^53)を超える巨大な2進数同士の加算でも、誤差なく正確な結果を得ることができます。

  1. JavaScriptで配列をSet(セット)に変換する方法

    JavaScriptで配列をSetに変換するときの基本JavaScriptでは、Setオブジェクトを使うことで、配列から重複しない一意の値だけを持つコレクションを簡単に作成できます。SetはES6(ECMAScript 2015)で導入された組み込みオブジェクトで、同じ値が複数回追加されても自動的に1つにまとめられるのが特徴です。変換自体は非常にシンプルで、new Set(配列)と書くだけで完了します。コード例:配列からSetへの変換以下は、重複を含む配列をSetに変換して画面に表示するサンプルコードです。<!DOCTYPE html> <html lang=ja> &

  2. JavaScriptのプロトタイプにメソッドを追加する方法

    JavaScriptのプロトタイプにメソッドを追加する方法JavaScriptでは、コンストラクタ関数のprototypeプロパティにメソッドを追加することで、そのコンストラクタから生成されたすべてのインスタンスが同じメソッドを共有できるようになります。各インスタンスに個別にメソッドを定義する必要がなくなるため、メモリの使用量を抑えられ、コードの保守性も向上します。以下は、JavaScriptのプロトタイプにメソッドを追加するコード例です。コード例<!DOCTYPE html> <html lang="ja"> <head> <me