HTML5テクニカルノート 2進数・16進数とビット演算
2進数や16進数の表し方と、2進数を基礎としたビット演算について簡単にご紹介します。
01 2進数2進数は0と1のみで数を表します。10進数が9に1を加えた10で繰り上がるのに対して、2進数は1に1を足した2で桁が上ります。したがって、2進数の10(= 1 + 1)は、10進数の2になる訳です。同じように、2進数の100と1000は、それぞれ10進数の4と8になります。ですからたとえば、2進数の1010は、つぎのように10進数の10と計算できます。 1×8 + 0×4 + 1×2 + 0×1 = 10 8は23、4は22、2は21、そして1は20ですから、上の式はつぎのように書直すこともできます。 1×23 + 0×22 + 1×21 + 0×20 = 10 一般に、2進数で表した数の各桁の小さい方から順に、n1、n2、...、nkとすると、これを10進数にするのはつぎの式になります。 nk×2k-1 + … + n2×21 + n1×20 また、10進数についても、各桁の数を小さい方から順に、n1、n2、...、nkとすれば、べき乗(累乗)される数を10に替えて、つぎのように示すことができます。 nk×10k-1 + … +n2×101 + n1×100 この考え方はさらに一般化できますので、i進数(iは正の整数)はつぎの式で表されます。 nk×ik-1 + … + n2×i1 + n1×i0 02 複数のフラグをひとつの整数で表す2進数を使うと、複数の2値のフラグをひとつの数値で効率的に表すことができます。 たとえば、2値のフラグとなるBoolean型の変数が4つあったとします。仮に、変数をa、b、c、dとし、それぞれの値がtrue、false、true、falseだったとしましょう。このとき、4桁の2進数を考え、頭から変数a、b、c、dを当てはめて、trueを1、falseを0とすれば、4つのフラグの値は以下のように2進数1010で表されます。したがって、10進数の10でフラグaとcがオン(true)であることを示せます。
03 ビットごとの論理演算子ビットごとの論理演算子は、2進数を各桁ごとに演算し、他の桁には影響を与えません。つまり、繰り上がりや繰り下がりがなく、結果は0か1のいずれかになります。オペランド(被演算子)も0か1ですので、4とおりの組合わせが考えられ、ビットごとの論理和演算子|の演算結果は下表001のとおりです。 表001■ビットごとの論理和演算子|の演算結果
「論理和」という名称は、条件を指定するときの論理和演算子||にも使われていました。この演算子は、オペランドがブール(論理)値の場合、いずれか一方がtrueであればtrueを返します。ビットごとの論理和演算子|も、同じように、オペランドのいずれか一方が1であれば1を返します。したがって、2進数で表記した1010 | 1100の演算結果は、2進数の1110となります。
ビットごとの論理演算子には、ほかにビットごとの論理積演算子&とビットごとの排他的論理和演算子^があります。ビットごとの論理積演算子&は、条件の論理積演算子&&と同じ考え方で、オペランドがともに1のときのみ1を返します(他の場合は0)。ビットごとの排他的論理和演算子^は、オペランドの一方のみが1のとき1を返し、それ以外は0を返します。下表002と003に、その演算結果を示します。 表002■ビットごとの論理積演算子&の演算結果
表003■ビットごとの排他的論理和演算子^の演算結果
04 16進数とRGBカラー値16進数もコンピュータではよく使われます。もちろん、16進数も前掲の式にしたがって、つぎのように表されます。 nk×16k-1 + … + n2×161 + n1×160 しかし、私たちが使う算用数字には、0から9までしかありません。そこで、それ以降はAからFまでのアルファベットで示されます。もっとも、16進数表記は、Webではよく見かけます。なじみが深いのはRGBカラー値でしょう。このRGBカラーも、赤(R)緑(G)青(B)それぞれに別の桁を割振ることにより、ひとつの値で3つのカラー成分値を表します(図001)。 図001■RGBカラー値
JavaScriptでは、16進数表記で整数を示すことができます。その場合、数値の前に0xを記述します。たとえば、ブルーの#0000FFは、つぎのように数値として表します。
それぞれのカラーが16進数ふた桁を使うのは、カラー成分値が0から255までの256階調であることにもとづきます。つまり、16進数で表しているとはいえ、実質256進数です。そこで、たとえば各カラー成分値が0から255までの整数で3つの変数に代入されていた場合、3つの成分を合わせたカラー値はつぎの式で求められます。 カラー値 = R成分値×2562 + G成分値×2561 + B成分値×2560 スクリプトでは、たとえば以下のように試すことができます。
ご参考までに、RGBのカラー成分を3つの引数としてカラー値の整数が得られる関数(getColorInt())を以下のコード001に示します。 console.log(getColorInt(0xFF, 0x33, 0x99)); // 16724889コード001■RGBカラー成分値からカラー整数値を得る関数
05 カラー値とビット演算16進数がコンピュータでよく使われるのは、値を2進数4桁で扱うことができるからです。つまり、16進数の0からFは、2進数の0から1111までの値になります。16進数で1桁繰り上がるつまり16を掛合わせるという処理は、2進数を左に4桁ずらすのと同じです。また、16進数で2桁繰り上げるのは256を掛ける演算で、2進数では8桁動かすことになります(図002)。 図002■256を掛ける処理は2進数で8桁左にずらすのと同じ
JavaScriptでは、この2進数で桁をずらすというビット演算ができます。左に桁をずらすには、ビットの左シフト演算子<<を使います。ビットの左シフト演算子<<の左側オペランドには2進数としてビット演算する対象の式、右側オペランドには左に動かすビット(桁)数を指定します。 すると、前掲コード001「RGBカラー成分値からカラー整数値を得る関数」(getColorInt())はつぎのコード002のように書き替えられます。もちろん、どちらの関数でも同じ結果が得られます。ただ、2進数をビットごとに扱う演算子は、繰り上がりや繰り下がりがなく、コンピュータのデジタル(1/0)のロジックにより近いため処理効率で勝るところがあります。 コード002■RGBカラー成分値からカラー整数値をビット演算で求める関数
逆に、RGBカラー値から各成分値を取出すには、ビットの右シフト演算子>>とビットごとの論理積演算子&を使います。以下のスクリプトの処理内容は、ビット演算の練習問題として考えていただくのにちょうどよいでしょう。理解しにくいときは、各値をそれぞれ2進数に変換(toString(2))して確かめ、演算の結果と比べてみることです。
前掲コード002とは逆に、カラーの整数値からRGB成分値を求める関数(getRgbComponents())は以下のコード003のように定めました。RGBの3成分値は、Objectインスタンス(rgbComponents)のプロパティとして納められます。 コード003■カラー整数値からRGBカラー成分値をビット演算で求める関数
作成者: 野中文雄 Copyright © 2001-2015 Fumio Nonaka. All rights reserved. |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||