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

JavaScriptでカスタムマッピングにより10進数を16進数へ変換するtoHex関数の実装方法

通常、10進数を16進数(基数16)に変換する際は、「0123456789ABCDEF」という文字セットを使って各桁の数値をマッピングします。

この記事では、同じ変換処理を行いながらも、標準の文字セットに縛られず、ユーザーが任意の文字列(スケール)を自由に指定できる関数の実装方法を解説します。

やりたいことの例

10進数 363 の16進数表記は「16B」です。
しかし、ユーザーが「0123456789ABCDEF」の代わりに、
たとえば「qwertyuiopasdfgh」というスケールを使うと決めた場合、
363 は「wus」と表現されます。

これが、今回実装したい機能です。

実装の考え方

再帰処理を利用して整数から16進数表現を組み立てる toHex() 関数を作成します。この関数は合計4つの引数を受け取りますが、エンドユーザーが実際に扱うのは最初の2つだけです。

  • 第1引数(num):16進数に変換したい数値。
  • 第2引数(hexString):カスタムスケール(省略可能)。指定する場合は必ず16文字の文字列である必要があり、それ以外の場合、関数は false を返します。
  • 第3引数(hex):結果を蓄積するための文字列。デフォルトは空文字列です(内部処理用)。
  • 第4引数(isNegative):負の数かどうかを示すブール値。デフォルトでは元の数値の符号から自動的に判定されます(内部処理用)。

コード例

const num = 363;
const toHex = (
    num,
    hexString = '0123456789ABCDEF',
    hex = '',
    isNegative = num < 0
    ) => {
    if(hexString.length !== 16){
       return false;
    }
    num = Math.abs(num);
    if(num && typeof num === 'number'){
       // 余りに対応する文字をhexの先頭に追加し、numを16で割りながら再帰呼び出し
       return toHex(Math.floor(num / 16), hexString,
       `${hexString[num%16]}${hex}`, isNegative);
    };
    return isNegative ? `-${hex}` : hex;
};
console.log(toHex(num, 'QWERTYUIOPASDFGH'));
console.log(toHex(num));
console.log(toHex(num, 'QAZWSX0123456789'));

出力

コンソールには次のように表示されます。

WUS
16B
A05

処理の流れのポイント

この関数は、数値を16で割った余りに対応する文字をスケールから取り出し、結果文字列の先頭に付け加えながら、商に対して自分自身を再帰的に呼び出します。商が0になった時点で再帰を終了し、これまでに組み立てた文字列を返します。

また、Math.abs() で絶対値に変換してから処理を行うため、負の数を渡した場合でも、先頭にマイナス記号が付いた正しい結果が得られます。さらに、第2引数を省略すれば標準の文字セットが使われるため、一般的な16進数表記と同様の変換結果になります。16文字以外の文字列をスケールとして渡した場合は false が返る仕組みなので、入力チェックの面でも安全な設計といえるでしょう。

  1. JavaScriptで1/nの循環小数(循環節)の長さを求める方法

    問題数値 num を第一引数(かつ唯一の引数)として受け取るJavaScript関数を作成します。この関数には、次の2つの役割があります。まず、その数が10と互いに素(共通の約数が1のみ)であるかどうかを判定します。互いに素でない場合は -1 を返します。10と互いに素である場合は、1をその数で割ったときに小数部が循環する桁数(循環節の長さ)を返します。たとえば、関数への入力が次の場合を考えてみましょう。入力const num = 123;出力const output = 5;出力の解説123は2でも5でも割り切れないため、確実に10と互いに素です。そして1を123で割ると、次のようになります

  2. JavaScriptで整数のビットが交互になっているかを判定する方法

    問題整数 num を唯一の引数として受け取るJavaScript関数を作成することを考えます。この関数の役割は、num の2進数表現におけるビットが「交互(オルタネーティング)」になっているかどうかを判定することです。つまり、隣り合うビットが常に異なる値を持つかどうかを確認します。例として、関数に次の入力を与えた場合を見てみましょう。入力const num = 5;出力const output = true;出力の説明5 の2進数表現は 101 であり、0と1が交互に並んでいるため、結果は true となります。解決アプローチ①:2進数の文字列を走査する最も直感的な方法は、数値を2進数の文字列