ビット演算について(Rubyでの演算方法)

f:id:ryoutaku_jo:20190718232953p:plain

【結論】

・ビット演算は、電気のON/OFFをビット(2進数の1桁)で表現し、それらを組み合わせることで、コンピュータに様々な演算を行わせること

・ビット演算子とは、整数に対してビット単位での演算を行う為の演算子

&論理積|論理和^排他的論理和~でビット反転、>>で右ビットシフト、<<で左ビットシフトを行うことが出来る

【目次】

【本題】

ビット演算について

コンピューターは、電気のON/OFFという電気信号で様々な処理を行います。

その電気のON/OFFを数値で表したものがビット(2進数の1桁)です。

コンピュータは、ビットの組み合わせによる演算を高速で行うことで、複雑な処理を実行しています。

ビット演算子について

ビット単位の計算を整数(10進数)でも行えるのが、ビット演算子です。

ビット演算子には、主に以下の種類が存在します。

&・・・論理積(AND)

|・・・論理和(OR)

^・・・排他的論理和(XOR)

~・・・ビット反転

>>・・・右ビットシフト

<<・・・左ビットシフト

論理積(AND)

論理積(AND)とは、2つの入力のいずれも真であることを示す論理演算です。

ビット演算では、1が真(true)で、0が偽(false)を表します。

なので、論理積の場合、計算対象の数値が双方1であった場合のみ、1を返します。片方でも0であれば、0を返します。

11110
10100

↓論理積(両方1なら1、片方でも0なら0を返す)

10100

Rubyでは、&で求められます。

なお、10進数は.to_s(2)で2進数に変換ができます

#10進数「30」を2進数に変換すると"11110"
30.to_s(2)
=> "11110"

#10進数「20」を2進数に変換すると"10100"
20.to_s(2)
=> "10100"

#10進数「30」「20」の論理積は「20」
30 & 20
=> 20

論理和(OR)

論理和(OR)とは、2つの入力のいずれかが真であることを示す論理演算です。

ビット演算では、計算対象の数値が片方でも1であった場合、1を返します。両方とも0であれば、0を返します。

11110
10100

↓論理和(片方でも1なら1、両方0なら0を返す)

11110

Rubyでは、|で求められます。

#10進数「30」「20」の論理和は「30」
30 | 20
=> 30

排他的論理和(XOR)

排他的論理和(XOR)とは、2つの入力のどちらか片方が真でもう片方が偽の時に真となり、両方とも真か偽の時は偽となる論理演算です。

ビット演算では、計算対象の数値がそれぞれ1と0の場合、1を返します。両方とも0か1であれば、0を返します。

11110
10100

↓ 排他的論理和(不一致なら1、一致なら0を返す)

01010

Rubyでは、^で求められます。

#10進数「30」「20」の論理和は「30」
30 ^ 20
=> 10

10.to_s(2)
=> "1010"

ビット反転

ビット反転とは、ビットの1と0を反転させる演算です。

11110

↓ ビット反転(1と0を反転)

00001

Rubyでは、~で求められます。

なお、負数については、2の補数(ビットを反転させて1を足す)で表します。

ryoutaku-jo.hatenablog.com

#10進数「30」をビット反転させると「-31」
~30
=> -31

31.to_s(2)
=> "11111"

#2の補数に変換
 "00001"

右ビットシフト

右ビットシフトは、ビット列全体を右にズラす算術シフトと呼ばれる処理です。

ズレたことによって空いた枠には0が入ります。

11110

↓ 右ビットシフト(ビット列全体を右にズラし、空いた枠に0を挿入。今回は一つだけズラす)

01111

Rubyでは、>>で求められます。

#左辺の数値を右辺の値だけ左へシフト
30 << 1
=> 60

15.to_s(2)
=> "1111"

左ビットシフト

左ビットシフトは、ビット列全体を左にズラす算術シフトです。

ズレたことによって空いた枠には0が入ります。

011110

↓ 左ビットシフト(ビット列全体を左にズラし、空いた枠に0を挿入。今回は一つだけズラす)

111100

Rubyでは、<<で求められます。

#左辺の数値を右辺の値だけ右へシフト
30 << 1
=> 60

60.to_s(2)
=> "111100"

参考情報

ビット演算 - Wikipedia

ビット演算入門 - Qiita

シフト演算子 - 数値と四則演算 - Ruby入門

《今日の学習進捗(3年以内に10000時間に向けて)》

飲み過ぎ辛い・・・

学習開始からの期間 :222日
今日までの合計時間:2131h
一日あたりの平均学習時間:9.6h
今日までに到達すべき目標時間:2027h
目標との解離:104h
「10,000時間」まで、

残り・・・「7869時間!」