WikiはScratcherによって作られています。(差分)この項目は、書きかけの項目です。この項目を加筆・訂正などしてくださる協力者を求めています。ここでは、scratchで二進数(2進数、二進法、バイナリ、バイナリ―、binary)を扱う方法を説明する。以降の説明で、10進数と対をなす意味で"二進数"と言う単語が使われる場合は"2進数"と表記する。この記事のスクリプトで使用している定義はすべてこのページ内に定義している物を使用している。二進数は、10進数での2を底として、数を表現する方法である。底とは、ある位が桁上げして"0"になるために必要な最大の数値のことである。二進数の表記<10進数>0,1,2,3,4,5,6,7,8,9,10←10が底(この例だと10で1の位が0になる)<2進数>0,0,1,10←2が底(2進数では"10"と言う表記は10進数の"2"を表す)また、他の進数表記と混同することを防ぐため2進数には表記上数値の後に"(2)"を付けることがある。プログラムで扱う数値には"(2)"は付かないので注意。←"(2)"が付いていないので10進数("(10)"と表記する場合もあるが、一般的には付けない事のほうが多い)10101101(8)←この場合は8進数10101101(16)←この場合は16進数2進数を10進数に変換する10010010(2)を10進数に変換する方法を次に示す。}と言う式で表すことができる。この式の"N"は2進数の1か0のどちらかを表し、dは右から何桁目かを表している。この式に10010010(2)を当てはめると以下のようになる。146次に上の式をscratchで実装する際の例を以下に示す。v]を(1)ずつ変える::variables}::control10進数を2進数に変換する10進数を2進数に変換する場合、最も簡単なのは10進数のある値を余りが1か0になるまで2で割り、その余りを並べるというものだろう。scratchでも、10進数から2進数への変換は変数2つで簡単に実装することができる。論理演算とは、各桁を真偽値で評価する演算である。論理演算には、論理和(or)/論理積(and)/否定(not)/排他的論理和(xor)/否定論理和(nor)/否定論理積(nand)/否定排他的論理和(nxor)の7つがある。否定(not演算)否定は、入力値が1つである唯一の論理演算である。入力された二進数の桁すべてを反転させる。v]を((二進数出力)と(1)::operators)にする::variable}::control}::control論理和(or演算)と否定論理和(nor演算)論理和は、2つ以上の入力された値の共通桁において、"1"が1つでも含まれる場合は"1"を出力する。否定論理和は論理和の出力を反転させたものである。v]を((二進数出力)と(1)::operators)にする::variable}::control}::control}::control否定論理和は、論理和の結果を否定演算すれば良いだけなのでスクリプトは省略する。論理積(and演算)と否定論理積(nand演算)論理積は、2つ以上の入力された値の共通桁に置いて、すべてを掛けた結果が"1"だった場合のみ1を出力する演算である。否定論理積は論理積の出力を反転させたものである。v]を((二進数出力)と(1)::operators)にする::variable}::control}::control}::control否定論理積は、論理積の結果を否定演算すれば良いだけなのでスクリプトは省略する。排他的論理和(xor演算)と否定排他的論理和(nxor演算)排他的論理和は、2つの入力された値の共通桁に置いて、どちらかの桁が"1"の場合のみ1を出力する演算である。v]を((二進数出力)と(1)::operators)にする::variable}::control}::control}::control二進数の算術演算scratchでは二進数の計算はサポートされていない。一度10進数に戻してから計算し、2進数に戻すという方法で一部の算術演算は簡単に実装することができる。自然数同士の加算/乗算は、演算結果に負数もしくは小数を含まないため、以下のスクリプトで十分に対応することができる。以下のスクリプトに登場する定義はすべて前述のものを利用している。自然数同士の減算を行った場合でも、結果が負の値を取る場合がある。ここでは、二進数での負数の表し方と二進数の減算について解説する。二進数で負の数を表現するためには、一般的に"2の補数"と呼ばれるものを使用する。2の補数とは、固定長ビット列において負数を表現する方法であり、内部的には加算で減算を表現するために使用される負数の表現方法である。10進数で、5-8を加算で表現すると、5+(-8)と表すことができるように、負の数を足すことで減算を表現できる。この表現は固定長(例えば32桁で二進数の桁を固定する表現)以外の表現では使用することができない。2の補数は二進数のすべての桁を反転し、1を足すことで求めることができる。1001101(2)の2の補数を求める場合、すべての桁を反転し0110010(2)にし、これに1を加算して0110011(2)2の補数を求めることができる2の補数が元の数の負数を表すことは、元の数とその数の2の補数を足して最上位桁以外が0になることから証明することができる。10000000この最上位桁以降はすべての桁が1である。いうと2の補数を求める際、すべての桁を反転させているからである。固定長ではない二進数の場合、最上位桁より先の桁は、永遠に1が続いていることになるため、固定長での二進数以外での2の補数表現は困難である。上記の証明から、二進数をプログラムとして扱う場合は固定長のほうが都合がよいことが分かった。よって、下記に二進数を固定長に整形するスクリプトを示す。v]を(スタック)にする::variable}::control補数表現と普通の数値との区別の仕方2の補数はある数値の負の値を表現する方法であると書いたが、2の補数を負の数値として扱うかどうかはプログラム側にゆだねられている。1011010(2)と言う二進数の数値を普通の数値として10進数に変換して"90"という数値として扱うのか、それとも2の補数として10進数に変換して"-36"という数値として扱うのかを決めるのはプログラム側の処理であるそこで、一般的に広く使われている区別の仕方は、最上位の桁を符号桁として扱う方法である。固定長二進数の最上位桁を"符号桁"として扱う。符号桁が0なら正の数値として処理することを表す。←この場合は最上位桁が"1"なので負の数値として処理すると言うように、正か負かを区別する符号桁を設けることでプログラムで負の値を区別することができる。テキストベースのプログラミング言語でデータ型(変数型)が設けられているのは、「この型なら32bitの長さの二進数で符号を区別するよ」などと、プログラムに処理の仕方を指定するためである。補数を求めるスクリプトを下記に示す。v]を((累乗記憶)*(2))にする::variable}::control10進数を2進数に変換((累乗記憶)-(10進数出力))::custom固定長に整形する(二進数出力)((二進数::custom-arg)の長さ)::custom2の補数表現に対応するパッチ"定義:10進数を2進数に変換"を2の補数に対応させ、符号付きの10進数を出力できるようにするパッチ定義を下記に示す。v]を((-)と((累乗記憶)-(10進数出力))::)にする::variable}::control上記のパッチは以下のようにして使用する。二進数の減算を行うスクリプトの例を下記に示す。このスクリプトは非常に低効率なので、高速な演算には向いていない。この処理に速度が必要な場合、工夫して高速化を図る必要がある。v]を((0)と(二進数出力)::operators)にする::variable}::controlシフト演算シフト演算とは、任意の固定長二進数列の数値を左右に指定桁ずらす演算のことである。シフト演算には、"論理シフト演算"と、"算術シフト演算"の2つの演算方法が存在する。論理シフト演算は単純に固定長二進数列を指定桁数ずらすだけの演算である。↓00011011論理シフト演算では、シフトされた結果空白になった桁は0で埋められる。算術シフト演算では、符号桁(固定長二進数列の最上位桁)が演算結果に作用するシフト演算である。↓11111001算術シフト演算で左にシフトする場合、最上位桁は固定され、その次の桁から下を左に指定数シフトする。シフトされた結果空白になった桁は0で埋められる。右にシフトする場合も最上位桁が固定されることは同じであるが、空白になった桁は符号桁の数値で埋められると言う違いがある。シフト演算の実装シフト演算を実装する例を下記に提示する。v]を(スタック)にする::variable}::control除算ここでは、二進数の除算の仕方と二進数における小数の表現方法を解説する。整数以下を割り切らない場合(余りを出す場合)整数同士の除算で整数以下を割り切らずに余りを出す場合、今までに説明してきた定義を使用し、簡単に除算を実装することができる。以下にスクリプトの例を示す。v]を(二進数出力)にする::variable10進数を2進数に変換((割られる数)を(割る数)で割った余り)::custom上記スクリプトの場合、商は変数"二進数出力"に格納され、余りは変数"一時記憶"に格納される。二進数における小数表現は"固定小数点数"と"浮動小数点数"の2種類が存在する。固定長の二進数のどこかの桁より下位の桁を小数として扱う表現方法である。10000101(2)例えば、上の二進数の右から4番目を1の位とすると、右から3番目以下の桁が小数部分である。小数点以下の桁は、1の位から1つ右にずれると1/2,さらに右にずれると1/4と言うように1/2ずつ桁の重みが変化する。固定小数点数の場合、余りを出さない除算をすることは非常に簡単である。各桁を右に1桁シフトするとその数値を2で割ったのと同じことになるからである。これは乗算にも言えることである。固定小数点数を実装するにあたって、注意すべきことがある。それは、"固定小数点数であるかどうかの区別はプログラム側が判断することである"ということである。1001010(2)を74として処理するのか、それとも18.5として処理するのか、または、2.3125として処理するのか(つまり小数点の位置もプログラム任せ)は補数と同じくプログラムが決めることである。この項目は書きかけです。浮動小数点数は、固定長の二進数を"符号部"、"指数部"、"仮数部"に分けることで小数を表現する。符号部には正か負か(+か-か)の値が入り、指数部には10を何乗するかを指定する。残りの仮数部には仮数の絶対値が入る。二進数の計算により発生する誤差コンピュータープログラムでの演算は、数列表現に限界があるため誤差が発生する場合がある。今節ではプログラム中で二進数を扱う際の誤差について解説する。丸め誤差は、限られた桁において四捨五入や切り上げ、切り下げなどの操作を行うことにより発生する誤差である。10進数の"0.1"を2進数で表現しようとすると"0.000110011..."となり、固定長の幅に収めることができない。そこで、ある桁で切り下げまたは切り上げの処理を行うことで発生する切り下げまたは切り上げした桁より下位の桁との差が丸め誤差である。打ち切り誤差とは、計算を途中で打ち切ることで発生する誤差である。円周率などの無限に続く計算を途中で打ち切ることで発生する。桁落ち桁落ちとは、絶対値が非常に小さい小数同士などの演算において、有効桁数が減少することで発生する誤差である。強制的に詰めるので、下位の桁が信頼できないものになる。情報落ち情報落ちとは、絶対値の大きい数値と小さい数値の差が著しい演算を行った際に有効桁が増えすぎるために演算結果に下位の桁の情報が反映されない現象である。桁あふれ演算結果がプログラムにおけるデータ型の扱うことができる桁を超えた場合にそれ以上大きい桁または小さい桁を表現しきれなくなることで起こる誤差である。指定桁より多いとオーバーフロー、小さい場合はアンダーフローと呼ぶ場合がある。4.0のライセンスで利用できます。DayScratchカンファレンスScratch。