進数と単位換算:非線形なのは温度だけ

2 から 36 進数の変換は BigInt で精度を守る必要があります。10 カテゴリのうち 9 つは線形の比率ですが、温度だけはアフィン変換で、単一の倍率では必ず間違えます。

進数変換はまず精度の扱いを決める

2 から 36 進数の変換は 10 を超えると文字を使いますが、解析規則自体は素直です。本当の問題は JavaScript の Number が倍精度浮動小数であることで、2 の 53 乗を超えると整数の下位ビットが静かに失われます。変換結果が黙って数桁欠けるのは、例外を投げるより悪い事態です。

そこで整数部分は BigInt を通します。任意精度で解析し、目的の進数で出力します。小数部分には精度が失われ得ることを明示します。十進と二進の小数はそもそも常に正確に相互変換できるわけではなく、正確なふりをするより明言するほうが良いからです。

二進数は区切って初めて読める

長い 0101 の並びは区切りがなければ読めません。4 ビット区切りは 16 進の 1 桁に揃い、8 ビット区切りはバイトに揃います。バイト表示はバイトごとに切り、十進と十六進を並べて示すので、プロトコルのフィールドを読むときは長い一串よりはるかに役立ちます。

10 カテゴリのうち 9 つは同じ形

長さ、重さ、面積、体積、データ、時間、速度、圧力、エネルギーはすべて線形です。互いに固定の比率しか違いません。したがって実装は一つで足り、各単位を基準単位へ換算してから目的の単位へ出します。データ単位は十進と二進の両方(KB と KiB)を示すべきです。そうしなければ「1 MB は 1000 KB か 1024 KB か」という議論がついて回ります。

温度だけが例外で、アフィン変換です。摂氏と華氏の間には比率とオフセットの両方があります。同じ比率表に温度を載せれば結果は必ず誤り、しかも誤りはゼロ以外でしか現れません。0 度はたまたま正しく見えるからです。

一度にすべてを並べる

換算ツールの価値は何度も入力しなくてよいことにあります。一つの値を入れると、そのカテゴリのすべての単位の等価量が一度に並びます。基準単位へ換えてから目的の単位へ、という二段階が不要になります。10 カテゴリを十個のツールに分けず、一つのページに置いた理由でもあります。

アサーションによる担保

この種の純粋関数は境界が明確です。摂氏 0 度は華氏 32 度(オフセットと比率の両方を同時に確認できます)、大きな整数は進数の往復で一致し、単位は変換して戻せば元の値に戻る。

← 記事一覧に戻る

コメント

…