「bit演算」の編集履歴(バックアップ)一覧はこちら

bit演算」(2018/06/06 (水) 13:22:01) の最新版変更点

追加された行は緑色になります。

削除された行は赤色になります。

//---- //:※解説修正情報※| //●&font(12,b){2013-01-XX:} // ---- -参考:「ADIのMUGENメモ」様の「bit演算のメモ」 *■bit演算 :| [[演算子]]の基本については該当ページを参照。 演算子の中でbit演算の仕様と応用を簡単に解説。 **■bitとは? :| 大雑把に言うとデータの最小単位のこと。 コンピューター内部のあらゆる情報は0or1の並びで管理されている。 特に数値情報は0,1のまま2進法として記録されている。 ''bit演算とはその0,1自体を比較する演算である。'' :| MUGENでは整数は32bit-Int型という形式で管理され、 小数を含む場合はFlaot型と呼ばれる特殊な形式になっている。 bit演算が可能なのはInt型に限られる。 :| なお利用する際は数式の優先度に注意。[[演算子]]のページを参照。 優先度はやや低いため、計算の順番を見誤ったりしないように。 #region(''■2進法・bit数値の読み方・32bit-Int型について'') **■2進法・bit数値の読み方 :| 2進法は使う数字が0と1しかないため1+1で一桁上がり10となる。 十進法での2が10、4が100、8が1000、16が10000、32が100000、 64なら1000000、128=10000000、256=100000000、512=1000000000、 1024=10000000000、2048=100000000000、~という具合。 コンピューターではこれらを組み合わせることで大きな数値を記録します。 |~bit情報|~十進法|例えば55はbit数値だと110111になるがそれは| |&tt(){0100000}|RIGHT:32|| |&tt(){0010000}|RIGHT:16|| |&tt(){0000000}|RIGHT:--|0のため無し| |&tt(){0000100}|RIGHT:4|| |&tt(){0000010}|RIGHT:2|| |&tt(){0000001}|RIGHT:1|| |&tt(){0110111}|RIGHT:55|上記の数値を組み合わせて表されているということ。| **■bitの動き :| 33+4=37という計算をbitで見ると以下のようになる。 |&tt(){100''0''01}|33| |&tt(){000''1''00}|+4| |&tt(){100''1''01}|37| 足した桁が0であればそのまま1が入る。1の場合は |&tt(){010''01''0}|18| |&tt(){000''01''0}|+2| |&tt(){010''10''0}|20| 合わさった箇所の桁が1つ上がる。 もちろん上がったbit桁の部分1ならさらに繰り上がりが発生する。 反対に89-24=65という計算のbitを見ると以下のように。 |&tt(){010''11''001}|89| |&tt(){000''11''000}|24| |&tt(){010''00''001}|65| マイナスなので丁度bitの重なる桁は0になっている。 0の部分をマイナスした場合は、 |&tt(){1''10000''1}|97| |&tt(){0''00001''1}|-3| |&tt(){1''01111''0}|94| 上側の一番近い1の桁を0にしその1つ下の桁からマイナスした桁まで1にする。 なお、上側に1がない場合は特別な状態となる。 **■32bit-Int型について :| 32bitの内、31bitまでは通常のbit演算だが、 bitの32桁目は''-2147483648''という数値になっている。 32bit全てが1の場合は、2147483647-2147483648となり-1の数値になる。 |&tt(){11111111111111111111111111111111}|RIGHT:-1|32bit-Int型の全て1の場合| |-|-|-| |&tt(){00000000000000000000000000101101}|RIGHT:45|この数から| |&tt(){00000000000000000000000010000000}|RIGHT:128|この数を引いた場合、| |&tt(){11111111111111111111111110101101}|RIGHT:-83|引いた数から上の桁が全て1に。| bitの32桁目は-2147483648のため、31桁目までの2147483565と合わせ 2147483565-2147483648=-83という状態として処理される。 ならもし31bitまで1の数値、2147483647に+1したら? |&tt(){01111111111111111111111111111111}|RIGHT:2147483647| |&tt(){00000000000000000000000000000001}|RIGHT:+1| |&tt(){10000000000000000000000000000000}|RIGHT:-2147483648| ''オーバーフローを起こし、マイナス数値に転じてしまう。'' なお''最初から最大値を超過している場合は、最大値まで補正される''。 オーバーフローが起きるのは計算によって超えた場合のみ。 ちなみに-1へ+1すると0になる。 |&tt(){11111111111111111111111111111111}|RIGHT:-1| |&tt(){00000000000000000000000000000001}|RIGHT:+1| |&tt(){00000000000000000000000000000000}|RIGHT:0| なお過度のオーバーフローはシステム上なるべく避けたほうが良い。 ''バグなどを引き起こす可能性もある'' **■2の冪(べき) :| 2進法の性質上bitの全ての桁は''2の累乗数''を表している。 1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192…という具合。 その為''2倍にするとbitの桁が全て1つ上がり'' ''(1桁目を除き)2で割るとbit桁が全て1下がる''という性質を持つ。 例えば、29で比較してみると |&tt(){00000''11101''}|RIGHT:29|ここから倍にすると| |&tt(){0000''11101''0}|RIGHT:58|1の場所が1つ上の桁にズレる。| |&tt(){000''11101''00}|RIGHT:116|さらに2倍しても同様。| |&tt(){00''11101''000}|RIGHT:232|倍にするとbit桁は繰り上がる。| |&tt(){0''11101''0000}|RIGHT:464|| |>|>|~この仕組みは2の累乗数でかけた場合も同様に、&br()対応するbitの桁数分増える。| |&tt(){00000''1101''}|RIGHT:13|13を| |&tt(){''0001''00000}|RIGHT:32|2の5乗である32を乗算すると| |&tt(){''1101''00000}|RIGHT:416|''32のbit桁まで13のbitがスライドする''。| この2の5乗で乗算するということは、5回分2倍にするのと同じ計算になる。 そして、''掛け算は同じ数の割り算で戻す事ができる''ように、 bitでも、2で割れば1桁下がり・''2の累乗数で割ればその分bitは下の桁へスライドする''。 |&tt(){''111''0000}|RIGHT:112|bitの一桁目(1)が無ければ、2で割ることができ、| |&tt(){0''111''000}|RIGHT:56|| |&tt(){00''111''00}|RIGHT:28|| |&tt(){000''111''0}|RIGHT:14|| |&tt(){0000''111''}|RIGHT:7|bitの一桁目(1)が出るまで、計算できる。| :| |&tt(){''11011''00000000}|RIGHT:6912|こんな大きな数値でも下の桁が0で| |&tt(){''00001''00000000}|RIGHT:256|対応する2の累乗数で割れば| |&tt(){00000000''11011''}|RIGHT:27|bitの数値をそのまま下の桁まで下ろせる。| :| ただし''MUGENでは小数が出た場合はbit管理はbit演算の使えないFloat型に切り替わるため、'' ''bit用の割り算には2の累乗数以外を使ってはならない''し、 ''用いる数値のbit桁未満の数値が存在しないこと''がMUGEN内では前提となる。 一応、小数が出ても[[T-/Floor()]]などで切り捨てれば、 1未満になった桁を省くことはできるが、数値そのものが不安定になるので避けるべき。 **■剰余と切り捨て :| 剰余(割り算の余り計算・MUGENでは演算子「%」)を用いると、 |&tt(){''110''110110}|RIGHT:438|ここから| |&tt(){''001''000000}|RIGHT:%64|2の累乗数を割ると、| |&tt(){''000''110110}|RIGHT:54|対応する桁以上を全て消せる。| :| Floor()と%剰余演算を組み合わせれば 「''特定した桁範囲のbitのみを取り出す''」こともできるが、 そうした計算は''bit演算子''を用いるほうが確実である。 |&tt(){''11011011''01011101}|RIGHT:56157|この数値から| |&tt(){''00000001''00000000}|RIGHT:/256|をした上で''Floor()で囲って小数を消し''| |&tt(){00000000''11011011''}|RIGHT:219|その後2で剰余計算をすると| |&tt(){00000000''00000001''}|RIGHT:1|指定したbitの桁が1か0かを確認できる。| |>|>|~のだが| |&tt(){1101101''1''01011101}|RIGHT:56157|この数値から| |&tt(){0000000''1''00000000}|RIGHT:&256|&「どちらも1」のbit演算を行うと| |&tt(){0000000''1''00000000}|RIGHT:256|そのまま指定bitの有無を確認できる。| Float型になると''細かい数値が浮動する危険もある''ので可能な限りInt型の方が良い。 次の項でbit演算についてを解説する。 #endregion #region(''■bit演算の読み方'') **■bit演算の読み方 :| ''bit演算とはbitの0,1自体を比較する演算である''わけだが、 mugenで使用出来る演算子は3種類。 &tt(){&font(20,b){「 & 」「 | 」「 ^ 」}} :| 基本的に計算式のように左右に数値を置いて使うのだが、 -「 & 」ANDは「''同じ桁のbitが1であればその桁は1、片方でも0なら0''」 -「 | 」ORは「''同じ桁のbitがどちらかでも1ならその桁は1に、両方0なら0''」 -「 ^ 」XORは「''同じ桁のbitの片方だけ1ならその桁は1、両方が同じなら0''」 --0&0=0 1&0=0 1&1=1、6&5=4 --0|0=0 1|0=1 1|1=1、6|5=7 --0^0=0 1^0=1 1^1=0、6^5=3 |SIZE(20):&tt(){0110}|RIGHT: 6|#|SIZE(20):&tt(){0110}|RIGHT: 6|#|SIZE(20):&tt(){0110}|RIGHT: 6| |SIZE(20):&tt(){0101}|RIGHT:&5|#|SIZE(20):&tt(){0101}|RIGHT:&nowiki(){|}5|#|SIZE(20):&tt(){0101}|RIGHT:^5| |SIZE(20):&tt(){0100}|RIGHT:=4|#|SIZE(20):&tt(){0111}|RIGHT:=7|#|SIZE(20):&tt(){0011}|RIGHT:=3| 基本的には|orと&andしか使わないが、^も応用方法はある。 #endregion ---- #region(''■32bit-Int型の表'') **■32bit-Int型の表 |RIGHT: 数値|~&tt(){21098765432109876543210987654321}|桁数|数値・bit桁の住所数値| |RIGHT: -2147483648|~&tt(){10000000000000000000000000000000}|32| (-2147483648 )| |RIGHT: 1073741824|~&tt(){01000000000000000000000000000000}|31| ( 1073741824 )| |RIGHT: 536870912|~&tt(){00100000000000000000000000000000}|30| ( 536870912 ) | |RIGHT: 268435456|~&tt(){00010000000000000000000000000000}|29| ( 268435456 ) | |RIGHT: 134217728|~&tt(){00001000000000000000000000000000}|28| ( 134217728 ) | |RIGHT: 67108864|~&tt(){00000100000000000000000000000000}|27| ( 67108864 ) | |RIGHT: 33554432|~&tt(){00000010000000000000000000000000}|26| ( 33554432 ) | |RIGHT: 16777216|~&tt(){00000001000000000000000000000000}|25| ( 16777216 ) | |RIGHT: 8388608|~&tt(){00000000100000000000000000000000}|24| ( 8388608 ) | |RIGHT: 4194304|~&tt(){00000000010000000000000000000000}|23| ( 4194304 ) | |RIGHT: 2097152|~&tt(){00000000001000000000000000000000}|22| ( 2097152 ) | |RIGHT: 1048576|~&tt(){00000000000100000000000000000000}|21| ( 1048576 ) | |RIGHT: 524288|~&tt(){00000000000010000000000000000000}|20| ( 524288 ) | |RIGHT: 262144|~&tt(){00000000000001000000000000000000}|19| ( 262144 ) | |RIGHT: 131072|~&tt(){00000000000000100000000000000000}|18| ( 131072 ) | |RIGHT: 65536|~&tt(){00000000000000010000000000000000}|17| ( 65536 ) | |RIGHT: 32768|~&tt(){00000000000000001000000000000000}|16| ( 32768 ) | |RIGHT: 16384|~&tt(){00000000000000000100000000000000}|15| ( 16384 ) | |RIGHT: 8192|~&tt(){00000000000000000010000000000000}|14| ( 8192 ) | |RIGHT: 4096|~&tt(){00000000000000000001000000000000}|13| ( 4096 ) | |RIGHT: 2048|~&tt(){00000000000000000000100000000000}|12| ( 2048 ) | |RIGHT: 1024|~&tt(){00000000000000000000010000000000}|11| ( 1024 ) | |RIGHT: 512|~&tt(){00000000000000000000001000000000}|10| ( 512 ) | |RIGHT: 256|~&tt(){00000000000000000000000100000000}|9| ( 256 ) | |RIGHT: 128|~&tt(){00000000000000000000000010000000}|8| ( 128 ) | |RIGHT: 64|~&tt(){00000000000000000000000001000000}|7| ( 64 ) | |RIGHT: 32|~&tt(){00000000000000000000000000100000}|6| ( 32 ) | |RIGHT: 16|~&tt(){00000000000000000000000000010000}|5| ( 16 ) | |RIGHT: 8|~&tt(){00000000000000000000000000001000}|4| ( 8 ) | |RIGHT: 4|~&tt(){00000000000000000000000000000100}|3| ( 4 ) | |RIGHT: 2|~&tt(){00000000000000000000000000000010}|2| ( 2 ) | |RIGHT: 1|~&tt(){00000000000000000000000000000001}|1| ( 1 ) | |RIGHT: 0|~&tt(){00000000000000000000000000000000}|-| ( 0 )| |RIGHT: 数値|~&tt(){21098765432109876543210987654321}|情報|bit住所数値| |RIGHT: 2147483647|~&tt(){01111111111111111111111111111111}|最大値|| |RIGHT: -2147483648|~&tt(){10000000000000000000000000000000}|最小値|| |RIGHT: -1|~&tt(){11111111111111111111111111111111}|全て1|| 後述するものには不可欠なもの。 単一の基本値であればFloor(2.0** xbit桁数-1x )でbit住所の代用は可能。 基本的には十進法と2進法との互換性を持った電卓ソフトを併用する。 #endregion ---- #region(''■Var-桁数分割方式について'') bit演算はvarの分割管理に有用なのだが、少し補足。 **■桁数分割管理について。 :| [[T-/Var()]]に入れる情報を桁数で分割して 単一のVarに複数の情報を入れられるようにすることを ''Varの分割管理''、桁数分割管理などと呼ぶ。''Var圧縮''とも。 代表例は[[T-/Floor()]]・/・%を用いて十進法の桁数を分割管理する通常の桁数分割管理。 **■Var-bit桁数分割方式について :| 入れる情報をbitの桁数で分割してより無駄なく使うのがbit桁数分割方式。 原理としてはbit桁数で別々に管理するようにする方式で、 bitを1~10・11~20・21~30桁目と分ければ''10bit(0~1023)の情報を3つ記録できる''。 もちろん10bitずつだけでなく5bit×2と20bitといった組分せも可能。 :| とはいえ1bitずつフラグ管理に使われるのが主。 大量Varでフラグ管理をしていてVarの余りが少なくなるような場合は必須。 **■通常の桁数分割とbit桁数分割の違い :| 「1か0」のフラグ管理は通常の桁数分割だと10+1個までしか管理できないが、 bitには「1か0」を記憶する桁が31+1個あるのでおよそ3倍もの数を管理ができる。 また0~1000までの数値も桁数分割では2個しかはいらないが、bitなら3個も入る。 :| とは言え桁数分割の方の10分割は0か1が1個+0~9が9個それぞれの情報量は多く、 2分割なら0~9999まで+0~213747までの数値と、かなりロスが出ているのだが。 特に通常の桁数分割方式の場合、0~4までを9個・0,1(5)を10個・+-という分割も可能で、 この場合、bitに換算すると3bitクラス×9+1bit×11と38bit分もの情報である。 (0~4の管理に3bitでは5~7のロスが生じ、それが9個重なり、6bitの差となっている。) **fvar、Float型とbit演算 Float型は32bit-Int型と同じ32bitの情報だが形式は全く異なり、 -1フラグの他小数数値や乗算用の数値で分かれており小数を扱える反面bit計算に適さない。 その為、基本的にFvarでbit演算を行うことはない。 なおFloat型・Fvarでも2の冪であれば、2の31乗まで確実に記録することができる。 #endregion #region(''■Var-bit桁数分割方式・使い方'') **■Var-bit桁数分割方式・使い方 :何もにも考えずに使いたい場合用・0,1フラグ管理| -代入・1にする --&nowiki(){Var(xx) := ( Var(xx) | (Floor( 2.0**(使う桁-1) )) )} -代入・0にする --&nowiki(){Var(xx) := ( Var(xx) & (Floor( 2.0**(使う桁-1) )^-1) )} -代入・フラグ条件式 --&nowiki(){Var(xx) := ( Var(xx) & (Floor( 2.0**(使う桁-1) )^-1) ) + (Floor( 2.0*(使う桁-1) ))*(条件式)} -確認/0or1式 -- &nowiki(){!( !(Var(xx)&(Floor( 2.0**(使う桁-1) ))) )} -使える桁数は1~32まで。 :あまり考えずに使いたい場合用・範囲数値管理| -まず1~32のどこからどこまでを使用するか決める。 --使用する桁範囲の一番小さい桁(''場所'')と、使用する桁数(''範囲'')を決める。 --仮に5~8桁目を使うとしたら、''場所''が5、5,6,7,8なので4桁の''範囲''。 -代入 --&nowiki(){Var(xx) := ( Var(xx) & (((Floor( 2.0**(範囲) )-1)*Floor( 2.0**(場所-1) ))^-1) ) + ( 代入する数値 )*(Floor( 2.0**(場所-1) )-1)} --※''範囲以上の数値を代入すると上側の桁にはみ出してしまうのて注意'' --必要なら、予め代入する数値を上限値に制限したりすること --&nowiki(){Ifelse((Floor( 2.0**(範囲) )-1)>代入予定値,代入予定値,(Floor( 2.0**(範囲) )-1))} -確認 --&nowiki(){( Var(xx) & ((Floor( 2.0**(範囲) )-1)*Floor( 2.0**(場所-1) )) ) / Floor( 2.0**(場所-1) )} :※注意点| -※桁数がかぶっていたりすると上手く処理されない。 -※32bitのため、bitに32桁より大きい桁は存在しない。 -※範囲桁数以上の数値を代入してはいけない。 -※''Floor内の2.0はMUGENでの冪乗計算を安定させるために必須''。 **■上記の解説 :フラグ管理の項目| -まず目的のbit桁の住所数値はFloor( 2.0**(x-1) )で指定している。 --「-1」なのは2.0分を減算しないと1つ上の桁になってしまうため。 --bitの住所数値については上記の「32bit-Int型の表」を参照。 -そのbit住所の数値を|ORや&ANDで埋めたり確認したりしている。 -0にする際の「^-1」は''bitの全ての桁の0と1を反転させる''bit演算。 --内容は''「11111111111111111111111111111111」との^XOR'' --''指定したbit桁のみ1^1の=0となりそれ以外は全て1に''なる。 --そしてその数値と&ANDをすることで''目的の桁のみを0に''できる。 -なお「^XOR」を使わない除外方法は&br()Var(xx) := ( Var(xx) | (Floor( 2.0**(使う桁-1) )) ) - (Floor( 2.0**(使う桁-1) )) --「|or」で埋めてから減算を行うというもの。 :範囲数値管理の項目| -場所と範囲は必ず決めておかないといけない。 --場所は指定の桁まで*で上げる・指定の桁から/で下げることに使用。 --範囲は(Floor( 2.0**(範囲) )-1)と、使用する桁数の1つ上の桁を1にして-1。 --範囲8桁なら2の8乗である「256(100000000)」から-1の「255(11111111)」と ---(2の(指定桁数)乗)-1により、指定桁数分1の並んだbit数値を算出できる。 -代入する際は「(範囲*場所)^-1」で&AND演算して指定桁数を空に、&br()そこへ「代入数値*場所」を加算して代入する。 -確認する際は「(範囲*場所)」で&AND演算して指定桁数以外を空に、&br()その数値を/場所で桁を下ろすことで数値を確認する。 **■数値の直打ちについて :| -なおFloor()の部分は上記の「32bit-Int型の表」の対応数値を書いても構わない。 -15桁目であればbit住所は16384なので( var(xx) & 16384 )みたいな具合。 --単純な記述のしやすさは上記の方が上だが、記述の単純さは数値を直に入力する方が楽。 -範囲指定の数値では桁数15,範囲5では&nowiki(){( var(xx) & ((16-1)*(16384)) )/(16384)}となるが、 --()内の計算をまとめ( var(xx) & 245760 )/(16384)と記述しても良い。 -と言うより要領がわかっているならそうした数値を直に入力する方が良い。 --少々面倒ではあるが表を作り桁数と範囲の数値を併記しておけば非常に楽。 :| -実際に使用する数値を作りたい場合 --基本的には「32bit-Int型の表」の対応数値を利用する。 --範囲*場所用の数値も(範囲桁数+1の対応数値)-1に、&br()場所の対応数値を掛けた数値を予め用意しておくと良い。 --ただし''bitの32桁目がマイナス数値なので通常の電卓では算出できない。''&br()''「-2147483648」を直接計算すること。'' ---不安であれば32bit目を使わないか、個別の1bitフラグとして利用しよう。 **■bitの動きの例 :フラグ管理| |>|>|~1にする| |SIZE(22):&tt(){00000000000000001100''0''10101110101}|RIGHT:50549|この数値に対して12桁目を入れる。| |SIZE(22):&tt(){00000000000000000000''1''00000000000}|RIGHT:2048|Floor( 2.0 ** (12-1) )の数値をORすると| |SIZE(22):&tt(){00000000000000001100''1''10101110101}|RIGHT:52597|こうなる。ORなので指定桁が1なら変化無し。| |>|>|~0にする| |SIZE(22):&tt(){00000000000110110''1''01110110100110}|RIGHT:1793446|この数値から15桁目を削る| ||↓|| |SIZE(22):&tt(){00000000000000000''1''00000000000000}|RIGHT:16384|Floor( 2.0 ** (15-1) )から~| |SIZE(22):&tt(){11111111111111111''1''11111111111111}|RIGHT:-1|-1のXORで| |SIZE(22):&tt(){11111111111111111''0''11111111111111}|RIGHT:-16385|指定行のみ0にする。| ||↓|| |SIZE(22):&tt(){00000000000110110''1''01110110100110}|RIGHT:1793446|元数値と| |SIZE(22):&tt(){11111111111111111''0''11111111111111}|RIGHT:-16385|指定桁数値^-1数値とANDで| |SIZE(22):&tt(){00000000000110110''0''01110110100110}|RIGHT:1777062|指定桁のみを0にできる。| |SIZE(22):&tt(){}|RIGHT:|なお、&ANDなので0なら0のまま。| |SIZE(22):&tt(){00000000000000000''1''00000000000000}|RIGHT:16384|条件式は*条件で指定桁数値を加算。| |>|>|~確認する| |SIZE(22):&tt(){000000000-11001''0''1110010110001101}|RIGHT:3335565|この数値から17桁目を調査したいなら| |SIZE(22):&tt(){000000000000000''1''0000000000000000}|RIGHT:65536|Floor( 2.0 ** (17-1) )とANDをして| |SIZE(22):&tt(){000000000000000''0''0000000000000000}|RIGHT:0|存在するかどうかを確認。| |SIZE(22):&tt(){}|RIGHT:|対象桁があるならANDにつかった数値に。| |SIZE(22):&tt(){}|RIGHT:|なお記述例では!を2回重ねることで&br()存在するならAND値→0→1に変換。&br()存在しないなら0→1→0と変換している。| :範囲数値| |>|>|~処理の基本・範囲と場所| |SIZE(22):&tt(){00000000001100101110010110001101}|RIGHT:3335565|ここの12桁目から7桁分を使うなら| ||↓|| |SIZE(22):&tt(){00000000000000000000000010000000}|RIGHT:128|まず範囲のためにFloor( 2.0**7 )から| |SIZE(22):&tt(){00000000000000000000000001111111}|RIGHT:127|-1をして7桁の範囲数値に| |SIZE(22):&tt(){00000000000000000000100000000000}|RIGHT:2048|場所の12桁目Floor( 2.0 ** (12-1) )を| |SIZE(22):&tt(){00000000000000111111100000000000}|RIGHT:260096|範囲*場所の数値を作る。| |>|>|~代入する| |SIZE(22):&tt(){00000000000000111111100000000000}|RIGHT:260096|範囲*場所を-1とXORして| |SIZE(22):&tt(){11111111111111000000011111111111}|RIGHT:-260097|範囲*場所の反転を作り| |SIZE(22):&tt(){00000000001100101110010110001101}|RIGHT:3335565|元数値とANDをかけて| |SIZE(22):&tt(){00000000001100000000010110001101}|RIGHT:3335565|範囲数値を0にする| ||↓|| |SIZE(22):&tt(){00000000000000000000000001001000}|RIGHT:72|この数値を入れるとして| |SIZE(22):&tt(){00000000000000000000100000000000}|RIGHT:2048|場所値で掛けて| |SIZE(22):&tt(){00000000000000100100000000000000}|RIGHT:147456|代入する数値にし、| |SIZE(22):&tt(){00000000001100000000010110001101}|RIGHT:3335565|範囲数値を0にした元へ| |SIZE(22):&tt(){00000000001100100100010110001101}|RIGHT:3294605|加算して代入を完了| |>|>|~参照する・上記の加算後から数値を取り出す。| |SIZE(22):&tt(){00000000001100100100010110001101}|RIGHT:3294605|ここから| |SIZE(22):&tt(){00000000000000111111100000000000}|RIGHT:260096|範囲*場所とANDで| |SIZE(22):&tt(){00000000000000100100000000000000}|RIGHT:147456|範囲以外を0にしたあと| |SIZE(22):&tt(){00000000000000000000100000000000}|RIGHT:2048|場所値で割り| |SIZE(22):&tt(){00000000000000000000000001001000}|RIGHT:72|数値を取り出す。| #endregion #region(''■bit分割Var用Var表・txtファイル用'') **■bit分割Var用Var表・txtファイル用 #aa(){;Var表用の32bit分割表 bit住所値付き ;Var(**)1 =(1) = ;--bit--2 =(2) = ;--bit--3 =(4) = ;--bit--4 =(8) = ;--bit--5 =(16) = ;--bit--6 =(32) = ;--bit--7 =(64) = ;--bit--8 =(128) = ;--bit--9 =(256) = ;--bit-10 =(512) = ;--bit-11 =(1024) = ;--bit-12 =(2048) = ;--bit-13 =(4096) = ;--bit-14 =(8192) = ;--bit-15 =(16384) = ;--bit-16 =(32768) = ;--bit-17 =(65536) = ;--bit-18 =(131072) = ;--bit-19 =(262144) = ;--bit-20 =(524288) = ;--bit-21 =(1048576) = ;--bit-22 =(2097152) = ;--bit-23 =(4194304) = ;--bit-24 =(8388608) = ;--bit-25 =(16777216) = ;--bit-26 =(33554432) = ;--bit-27 =(67108864) = ;--bit-28 =(134217728) = ;--bit-29 =(268435456) = ;--bit-30 =(536870912) = ;--bit-31 =(1073741824)= ;--bit-32(-2147483648)= ;範囲用 ;-bit-xx-xx=(&x範囲値x)/x場所値x= } #endregion //|&tt(){}|RIGHT:|| //|&tt(){}|RIGHT:|| //|&tt(){}|RIGHT:|| //|&tt(){}|RIGHT:|| ----
//---- //:※解説修正情報※| //●&font(12,b){2013-01-XX:} // ---- -参考:「ADIのMUGENメモ」様の「bit演算のメモ」 *■bit演算 [[演算子]]の基本については該当ページを参照。 演算子の中でbit演算の仕様と応用を簡単に解説。 **■bitとは? 大雑把に言うとデータの最小単位のこと。 コンピューター内部のあらゆる情報は0or1の並びで管理されている。 特に数値情報は0,1のまま2進法として記録されている。 ''bit演算とはその0,1自体を比較する演算である。'' #br MUGENでは整数は32bit-Int型という形式で管理され、 小数を含む場合はFlaot型と呼ばれる特殊な形式になっている。 bit演算が可能なのはInt型に限られる。 #br なお利用する際は数式の優先度に注意。[[演算子]]のページを参照。 優先度はやや低いため、計算の順番を見誤ったりしないように。 #region(''■2進法・bit数値の読み方・32bit-Int型について'') **■2進法・bit数値の読み方 2進法は使う数字が0と1しかないため1+1で一桁上がり10となる。 十進法での2が10、4が100、8が1000、16が10000、32が100000、 64なら1000000、128=10000000、256=100000000、512=1000000000、 1024=10000000000、2048=100000000000、~という具合。 コンピューターではこれらを組み合わせることで大きな数値を記録します。 |~bit情報|~十進法|例えば55はbit数値だと110111になるがそれは| |&tt(){0100000}|RIGHT:32|| |&tt(){0010000}|RIGHT:16|| |&tt(){0000000}|RIGHT:--|0のため無し| |&tt(){0000100}|RIGHT:4|| |&tt(){0000010}|RIGHT:2|| |&tt(){0000001}|RIGHT:1|| |&tt(){0110111}|RIGHT:55|上記の数値を組み合わせて表されているということ。| **■bitの動き 33+4=37という計算をbitで見ると以下のようになる。 |&tt(){100''0''01}|33| |&tt(){000''1''00}|+4| |&tt(){100''1''01}|37| 足した桁が0であればそのまま1が入る。1の場合は |&tt(){010''01''0}|18| |&tt(){000''01''0}|+2| |&tt(){010''10''0}|20| 合わさった箇所の桁が1つ上がる。 もちろん上がったbit桁の部分1ならさらに繰り上がりが発生する。 反対に89-24=65という計算のbitを見ると以下のように。 |&tt(){010''11''001}|89| |&tt(){000''11''000}|24| |&tt(){010''00''001}|65| マイナスなので丁度bitの重なる桁は0になっている。 0の部分をマイナスした場合は、 |&tt(){1''10000''1}|97| |&tt(){0''00001''1}|-3| |&tt(){1''01111''0}|94| 上側の一番近い1の桁を0にしその1つ下の桁からマイナスした桁まで1にする。 なお、上側に1がない場合は特別な状態となる。 **■32bit-Int型について 32bitの内、31bitまでは通常のbit演算だが、 bitの32桁目は''-2147483648''という数値になっている。 32bit全てが1の場合は、2147483647-2147483648となり-1の数値になる。 |&tt(){11111111111111111111111111111111}|RIGHT:-1|32bit-Int型の全て1の場合| |-|-|-| |&tt(){00000000000000000000000000101101}|RIGHT:45|この数から| |&tt(){00000000000000000000000010000000}|RIGHT:128|この数を引いた場合、| |&tt(){11111111111111111111111110101101}|RIGHT:-83|引いた数から上の桁が全て1に。| bitの32桁目は-2147483648のため、31桁目までの2147483565と合わせ 2147483565-2147483648=-83という状態として処理される。 ならもし31bitまで1の数値、2147483647に+1したら? |&tt(){01111111111111111111111111111111}|RIGHT:2147483647| |&tt(){00000000000000000000000000000001}|RIGHT:+1| |&tt(){10000000000000000000000000000000}|RIGHT:-2147483648| ''オーバーフローを起こし、マイナス数値に転じてしまう。'' なお''最初から最大値を超過している場合は、最大値まで補正される''。 オーバーフローが起きるのは計算によって超えた場合のみ。 ちなみに-1へ+1すると0になる。 |&tt(){11111111111111111111111111111111}|RIGHT:-1| |&tt(){00000000000000000000000000000001}|RIGHT:+1| |&tt(){00000000000000000000000000000000}|RIGHT:0| なお過度のオーバーフローはシステム上なるべく避けたほうが良い。 ''バグなどを引き起こす可能性もある'' **■2の冪(べき) 2進法の性質上bitの全ての桁は''2の累乗数''を表している。 1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192…という具合。 その為''2倍にするとbitの桁が全て1つ上がり'' ''(1桁目を除き)2で割るとbit桁が全て1下がる''という性質を持つ。 例えば、29で比較してみると |&tt(){00000''11101''}|RIGHT:29|ここから倍にすると| |&tt(){0000''11101''0}|RIGHT:58|1の場所が1つ上の桁にズレる。| |&tt(){000''11101''00}|RIGHT:116|さらに2倍しても同様。| |&tt(){00''11101''000}|RIGHT:232|倍にするとbit桁は繰り上がる。| |&tt(){0''11101''0000}|RIGHT:464|| |>|>|~この仕組みは2の累乗数でかけた場合も同様に、&br()対応するbitの桁数分増える。| |&tt(){00000''1101''}|RIGHT:13|13を| |&tt(){''0001''00000}|RIGHT:32|2の5乗である32を乗算すると| |&tt(){''1101''00000}|RIGHT:416|''32のbit桁まで13のbitがスライドする''。| この2の5乗で乗算するということは、5回分2倍にするのと同じ計算になる。 そして、''掛け算は同じ数の割り算で戻す事ができる''ように、 bitでも、2で割れば1桁下がり・''2の累乗数で割ればその分bitは下の桁へスライドする''。 |&tt(){''111''0000}|RIGHT:112|bitの一桁目(1)が無ければ、2で割ることができ、| |&tt(){0''111''000}|RIGHT:56|| |&tt(){00''111''00}|RIGHT:28|| |&tt(){000''111''0}|RIGHT:14|| |&tt(){0000''111''}|RIGHT:7|bitの一桁目(1)が出るまで、計算できる。| :| |&tt(){''11011''00000000}|RIGHT:6912|こんな大きな数値でも下の桁が0で| |&tt(){''00001''00000000}|RIGHT:256|対応する2の累乗数で割れば| |&tt(){00000000''11011''}|RIGHT:27|bitの数値をそのまま下の桁まで下ろせる。| :| ただし''MUGENでは小数が出た場合はbit管理はbit演算の使えないFloat型に切り替わるため、'' ''bit用の割り算には2の累乗数以外を使ってはならない''し、 ''用いる数値のbit桁未満の数値が存在しないこと''がMUGEN内では前提となる。 一応、小数が出ても[[T-/Floor()]]などで切り捨てれば、 1未満になった桁を省くことはできるが、数値そのものが不安定になるので避けるべき。 **■剰余と切り捨て 剰余(割り算の余り計算・MUGENでは演算子「%」)を用いると、 |&tt(){''110''110110}|RIGHT:438|ここから| |&tt(){''001''000000}|RIGHT:%64|2の累乗数を割ると、| |&tt(){''000''110110}|RIGHT:54|対応する桁以上を全て消せる。| #br Floor()と%剰余演算を組み合わせれば 「''特定した桁範囲のbitのみを取り出す''」こともできるが、 そうした計算は''bit演算子''を用いるほうが確実である。 |&tt(){''11011011''01011101}|RIGHT:56157|この数値から| |&tt(){''00000001''00000000}|RIGHT:/256|をした上で''Floor()で囲って小数を消し''| |&tt(){00000000''11011011''}|RIGHT:219|その後2で剰余計算をすると| |&tt(){00000000''00000001''}|RIGHT:1|指定したbitの桁が1か0かを確認できる。| |>|>|~のだが| |&tt(){1101101''1''01011101}|RIGHT:56157|この数値から| |&tt(){0000000''1''00000000}|RIGHT:&256|&「どちらも1」のbit演算を行うと| |&tt(){0000000''1''00000000}|RIGHT:256|そのまま指定bitの有無を確認できる。| Float型になると''細かい数値が浮動する危険もある''ので可能な限りInt型の方が良い。 次の項でbit演算についてを解説する。 #endregion #region(''■bit演算の読み方'') **■bit演算の読み方 ''bit演算とはbitの0,1自体を比較する演算である''わけだが、 mugenで使用出来る演算子は3種類。 &tt(){&font(20,b){「 & 」「 | 」「 ^ 」}} #br 基本的に計算式のように左右に数値を置いて使うのだが、 -「 & 」ANDは「''同じ桁のbitが1であればその桁は1、片方でも0なら0''」 -「 | 」ORは「''同じ桁のbitがどちらかでも1ならその桁は1に、両方0なら0''」 -「 ^ 」XORは「''同じ桁のbitの片方だけ1ならその桁は1、両方が同じなら0''」 --0&0=0 1&0=0 1&1=1、6&5=4 --0|0=0 1|0=1 1|1=1、6|5=7 --0^0=0 1^0=1 1^1=0、6^5=3 |SIZE(20):&tt(){0110}|RIGHT: 6|#|SIZE(20):&tt(){0110}|RIGHT: 6|#|SIZE(20):&tt(){0110}|RIGHT: 6| |SIZE(20):&tt(){0101}|RIGHT:&5|#|SIZE(20):&tt(){0101}|RIGHT:&nowiki(){|}5|#|SIZE(20):&tt(){0101}|RIGHT:^5| |SIZE(20):&tt(){0100}|RIGHT:=4|#|SIZE(20):&tt(){0111}|RIGHT:=7|#|SIZE(20):&tt(){0011}|RIGHT:=3| 基本的には|orと&andしか使わないが、^も応用方法はある。 #endregion ---- #region(''■32bit-Int型の表'') **■32bit-Int型の表 |RIGHT: 数値|~&tt(){21098765432109876543210987654321}|桁数|数値・bit桁の住所数値| |RIGHT: -2147483648|~&tt(){10000000000000000000000000000000}|32| (-2147483648 )| |RIGHT: 1073741824|~&tt(){01000000000000000000000000000000}|31| ( 1073741824 )| |RIGHT: 536870912|~&tt(){00100000000000000000000000000000}|30| ( 536870912 ) | |RIGHT: 268435456|~&tt(){00010000000000000000000000000000}|29| ( 268435456 ) | |RIGHT: 134217728|~&tt(){00001000000000000000000000000000}|28| ( 134217728 ) | |RIGHT: 67108864|~&tt(){00000100000000000000000000000000}|27| ( 67108864 ) | |RIGHT: 33554432|~&tt(){00000010000000000000000000000000}|26| ( 33554432 ) | |RIGHT: 16777216|~&tt(){00000001000000000000000000000000}|25| ( 16777216 ) | |RIGHT: 8388608|~&tt(){00000000100000000000000000000000}|24| ( 8388608 ) | |RIGHT: 4194304|~&tt(){00000000010000000000000000000000}|23| ( 4194304 ) | |RIGHT: 2097152|~&tt(){00000000001000000000000000000000}|22| ( 2097152 ) | |RIGHT: 1048576|~&tt(){00000000000100000000000000000000}|21| ( 1048576 ) | |RIGHT: 524288|~&tt(){00000000000010000000000000000000}|20| ( 524288 ) | |RIGHT: 262144|~&tt(){00000000000001000000000000000000}|19| ( 262144 ) | |RIGHT: 131072|~&tt(){00000000000000100000000000000000}|18| ( 131072 ) | |RIGHT: 65536|~&tt(){00000000000000010000000000000000}|17| ( 65536 ) | |RIGHT: 32768|~&tt(){00000000000000001000000000000000}|16| ( 32768 ) | |RIGHT: 16384|~&tt(){00000000000000000100000000000000}|15| ( 16384 ) | |RIGHT: 8192|~&tt(){00000000000000000010000000000000}|14| ( 8192 ) | |RIGHT: 4096|~&tt(){00000000000000000001000000000000}|13| ( 4096 ) | |RIGHT: 2048|~&tt(){00000000000000000000100000000000}|12| ( 2048 ) | |RIGHT: 1024|~&tt(){00000000000000000000010000000000}|11| ( 1024 ) | |RIGHT: 512|~&tt(){00000000000000000000001000000000}|10| ( 512 ) | |RIGHT: 256|~&tt(){00000000000000000000000100000000}|9| ( 256 ) | |RIGHT: 128|~&tt(){00000000000000000000000010000000}|8| ( 128 ) | |RIGHT: 64|~&tt(){00000000000000000000000001000000}|7| ( 64 ) | |RIGHT: 32|~&tt(){00000000000000000000000000100000}|6| ( 32 ) | |RIGHT: 16|~&tt(){00000000000000000000000000010000}|5| ( 16 ) | |RIGHT: 8|~&tt(){00000000000000000000000000001000}|4| ( 8 ) | |RIGHT: 4|~&tt(){00000000000000000000000000000100}|3| ( 4 ) | |RIGHT: 2|~&tt(){00000000000000000000000000000010}|2| ( 2 ) | |RIGHT: 1|~&tt(){00000000000000000000000000000001}|1| ( 1 ) | |RIGHT: 0|~&tt(){00000000000000000000000000000000}|-| ( 0 )| |RIGHT: 数値|~&tt(){21098765432109876543210987654321}|情報|bit住所数値| |RIGHT: 2147483647|~&tt(){01111111111111111111111111111111}|最大値|| |RIGHT: -2147483648|~&tt(){10000000000000000000000000000000}|最小値|| |RIGHT: -1|~&tt(){11111111111111111111111111111111}|全て1|| 後述するものには不可欠なもの。 単一の基本値であればFloor(2.0** xbit桁数-1x )でbit住所の代用は可能。 基本的には十進法と2進法との互換性を持った電卓ソフトを併用する。 #endregion ---- #region(''■Var-桁数分割方式について'') bit演算はvarの分割管理に有用なのだが、少し補足。 **■桁数分割管理について。 [[T-/Var()]]に入れる情報を桁数で分割して 単一のVarに複数の情報を入れられるようにすることを ''Varの分割管理''、桁数分割管理などと呼ぶ。''Var圧縮''とも。 代表例は[[T-/Floor()]]・/・%を用いて十進法の桁数を分割管理する通常の桁数分割管理。 **■Var-bit桁数分割方式について 入れる情報をbitの桁数で分割してより無駄なく使うのがbit桁数分割方式。 原理としてはbit桁数で別々に管理するようにする方式で、 bitを1~10・11~20・21~30桁目と分ければ''10bit(0~1023)の情報を3つ記録できる''。 もちろん10bitずつだけでなく5bit×2と20bitといった組分せも可能。 #br とはいえ1bitずつフラグ管理に使われるのが主。 大量Varでフラグ管理をしていてVarの余りが少なくなるような場合は必須。 **■通常の桁数分割とbit桁数分割の違い 「1か0」のフラグ管理は通常の桁数分割だと10+1個までしか管理できないが、 bitには「1か0」を記憶する桁が31+1個あるのでおよそ3倍もの数を管理ができる。 また0~1000までの数値も桁数分割では2個しかはいらないが、bitなら3個も入る。 :| とは言え桁数分割の方の10分割は0か1が1個+0~9が9個それぞれの情報量は多く、 2分割なら0~9999まで+0~213747までの数値と、かなりロスが出ているのだが。 特に通常の桁数分割方式の場合、0~4までを9個・0,1(5)を10個・+-という分割も可能で、 この場合、bitに換算すると3bitクラス×9+1bit×11と38bit分もの情報である。 (0~4の管理に3bitでは5~7のロスが生じ、それが9個重なり、6bitの差となっている。) **fvar、Float型とbit演算 Float型は32bit-Int型と同じ32bitの情報だが形式は全く異なり、 -1フラグの他小数数値や乗算用の数値で分かれており小数を扱える反面bit計算に適さない。 その為、基本的にFvarでbit演算を行うことはない。 なおFloat型・Fvarでも2の冪であれば、2の31乗まで確実に記録することができる。 #endregion #region(''■Var-bit桁数分割方式・使い方'') **■Var-bit桁数分割方式・使い方 :何もにも考えずに使いたい場合用・0,1フラグ管理| -代入・1にする --&nowiki(){Var(xx) := ( Var(xx) | (Floor( 2.0**(使う桁-1) )) )} -代入・0にする --&nowiki(){Var(xx) := ( Var(xx) & (Floor( 2.0**(使う桁-1) )^-1) )} -代入・フラグ条件式 --&nowiki(){Var(xx) := ( Var(xx) & (Floor( 2.0**(使う桁-1) )^-1) ) + (Floor( 2.0*(使う桁-1) ))*(条件式)} -確認/0or1式 -- &nowiki(){!( !(Var(xx)&(Floor( 2.0**(使う桁-1) ))) )} -使える桁数は1~32まで。 :あまり考えずに使いたい場合用・範囲数値管理| -まず1~32のどこからどこまでを使用するか決める。 --使用する桁範囲の一番小さい桁(''場所'')と、使用する桁数(''範囲'')を決める。 --仮に5~8桁目を使うとしたら、''場所''が5、5,6,7,8なので4桁の''範囲''。 -代入 --&nowiki(){Var(xx) := ( Var(xx) & (((Floor( 2.0**(範囲) )-1)*Floor( 2.0**(場所-1) ))^-1) ) + ( 代入する数値 )*(Floor( 2.0**(場所-1) )-1)} --※''範囲以上の数値を代入すると上側の桁にはみ出してしまうのて注意'' --必要なら、予め代入する数値を上限値に制限したりすること --&nowiki(){Ifelse((Floor( 2.0**(範囲) )-1)>代入予定値,代入予定値,(Floor( 2.0**(範囲) )-1))} -確認 --&nowiki(){( Var(xx) & ((Floor( 2.0**(範囲) )-1)*Floor( 2.0**(場所-1) )) ) / Floor( 2.0**(場所-1) )} :※注意点| -※桁数がかぶっていたりすると上手く処理されない。 -※32bitのため、bitに32桁より大きい桁は存在しない。 -※範囲桁数以上の数値を代入してはいけない。 -※''Floor内の2.0はMUGENでの冪乗計算を安定させるために必須''。 **■上記の解説 :フラグ管理の項目| -まず目的のbit桁の住所数値はFloor( 2.0**(x-1) )で指定している。 --「-1」なのは2.0分を減算しないと1つ上の桁になってしまうため。 --bitの住所数値については上記の「32bit-Int型の表」を参照。 -そのbit住所の数値を|ORや&ANDで埋めたり確認したりしている。 -0にする際の「^-1」は''bitの全ての桁の0と1を反転させる''bit演算。 --内容は''「11111111111111111111111111111111」との^XOR'' --''指定したbit桁のみ1^1の=0となりそれ以外は全て1に''なる。 --そしてその数値と&ANDをすることで''目的の桁のみを0に''できる。 -なお「^XOR」を使わない除外方法は&br()Var(xx) := ( Var(xx) | (Floor( 2.0**(使う桁-1) )) ) - (Floor( 2.0**(使う桁-1) )) --「|or」で埋めてから減算を行うというもの。 :範囲数値管理の項目| -場所と範囲は必ず決めておかないといけない。 --場所は指定の桁まで*で上げる・指定の桁から/で下げることに使用。 --範囲は(Floor( 2.0**(範囲) )-1)と、使用する桁数の1つ上の桁を1にして-1。 --範囲8桁なら2の8乗である「256(100000000)」から-1の「255(11111111)」と ---(2の(指定桁数)乗)-1により、指定桁数分1の並んだbit数値を算出できる。 -代入する際は「(範囲*場所)^-1」で&AND演算して指定桁数を空に、&br()そこへ「代入数値*場所」を加算して代入する。 -確認する際は「(範囲*場所)」で&AND演算して指定桁数以外を空に、&br()その数値を/場所で桁を下ろすことで数値を確認する。 **■数値の直打ちについて -なおFloor()の部分は上記の「32bit-Int型の表」の対応数値を書いても構わない。 -15桁目であればbit住所は16384なので( var(xx) & 16384 )みたいな具合。 --単純な記述のしやすさは上記の方が上だが、記述の単純さは数値を直に入力する方が楽。 -範囲指定の数値では桁数15,範囲5では&nowiki(){( var(xx) & ((16-1)*(16384)) )/(16384)}となるが、 --()内の計算をまとめ( var(xx) & 245760 )/(16384)と記述しても良い。 -と言うより要領がわかっているならそうした数値を直に入力する方が良い。 --少々面倒ではあるが表を作り桁数と範囲の数値を併記しておけば非常に楽。 #br -実際に使用する数値を作りたい場合 --基本的には「32bit-Int型の表」の対応数値を利用する。 --範囲*場所用の数値も(範囲桁数+1の対応数値)-1に、&br()場所の対応数値を掛けた数値を予め用意しておくと良い。 --ただし''bitの32桁目がマイナス数値なので通常の電卓では算出できない。''&br()''「-2147483648」を直接計算すること。'' ---不安であれば32bit目を使わないか、個別の1bitフラグとして利用しよう。 **■bitの動きの例 :フラグ管理| |>|>|~1にする| |SIZE(22):&tt(){00000000000000001100''0''10101110101}|RIGHT:50549|この数値に対して12桁目を入れる。| |SIZE(22):&tt(){00000000000000000000''1''00000000000}|RIGHT:2048|Floor( 2.0 ** (12-1) )の数値をORすると| |SIZE(22):&tt(){00000000000000001100''1''10101110101}|RIGHT:52597|こうなる。ORなので指定桁が1なら変化無し。| |>|>|~0にする| |SIZE(22):&tt(){00000000000110110''1''01110110100110}|RIGHT:1793446|この数値から15桁目を削る| ||↓|| |SIZE(22):&tt(){00000000000000000''1''00000000000000}|RIGHT:16384|Floor( 2.0 ** (15-1) )から~| |SIZE(22):&tt(){11111111111111111''1''11111111111111}|RIGHT:-1|-1のXORで| |SIZE(22):&tt(){11111111111111111''0''11111111111111}|RIGHT:-16385|指定行のみ0にする。| ||↓|| |SIZE(22):&tt(){00000000000110110''1''01110110100110}|RIGHT:1793446|元数値と| |SIZE(22):&tt(){11111111111111111''0''11111111111111}|RIGHT:-16385|指定桁数値^-1数値とANDで| |SIZE(22):&tt(){00000000000110110''0''01110110100110}|RIGHT:1777062|指定桁のみを0にできる。| |SIZE(22):&tt(){}|RIGHT:|なお、&ANDなので0なら0のまま。| |SIZE(22):&tt(){00000000000000000''1''00000000000000}|RIGHT:16384|条件式は*条件で指定桁数値を加算。| |>|>|~確認する| |SIZE(22):&tt(){000000000-11001''0''1110010110001101}|RIGHT:3335565|この数値から17桁目を調査したいなら| |SIZE(22):&tt(){000000000000000''1''0000000000000000}|RIGHT:65536|Floor( 2.0 ** (17-1) )とANDをして| |SIZE(22):&tt(){000000000000000''0''0000000000000000}|RIGHT:0|存在するかどうかを確認。| |SIZE(22):&tt(){}|RIGHT:|対象桁があるならANDにつかった数値に。| |SIZE(22):&tt(){}|RIGHT:|なお記述例では!を2回重ねることで&br()存在するならAND値→0→1に変換。&br()存在しないなら0→1→0と変換している。| :範囲数値| |>|>|~処理の基本・範囲と場所| |SIZE(22):&tt(){00000000001100101110010110001101}|RIGHT:3335565|ここの12桁目から7桁分を使うなら| ||↓|| |SIZE(22):&tt(){00000000000000000000000010000000}|RIGHT:128|まず範囲のためにFloor( 2.0**7 )から| |SIZE(22):&tt(){00000000000000000000000001111111}|RIGHT:127|-1をして7桁の範囲数値に| |SIZE(22):&tt(){00000000000000000000100000000000}|RIGHT:2048|場所の12桁目Floor( 2.0 ** (12-1) )を| |SIZE(22):&tt(){00000000000000111111100000000000}|RIGHT:260096|範囲*場所の数値を作る。| |>|>|~代入する| |SIZE(22):&tt(){00000000000000111111100000000000}|RIGHT:260096|範囲*場所を-1とXORして| |SIZE(22):&tt(){11111111111111000000011111111111}|RIGHT:-260097|範囲*場所の反転を作り| |SIZE(22):&tt(){00000000001100101110010110001101}|RIGHT:3335565|元数値とANDをかけて| |SIZE(22):&tt(){00000000001100000000010110001101}|RIGHT:3335565|範囲数値を0にする| ||↓|| |SIZE(22):&tt(){00000000000000000000000001001000}|RIGHT:72|この数値を入れるとして| |SIZE(22):&tt(){00000000000000000000100000000000}|RIGHT:2048|場所値で掛けて| |SIZE(22):&tt(){00000000000000100100000000000000}|RIGHT:147456|代入する数値にし、| |SIZE(22):&tt(){00000000001100000000010110001101}|RIGHT:3335565|範囲数値を0にした元へ| |SIZE(22):&tt(){00000000001100100100010110001101}|RIGHT:3294605|加算して代入を完了| |>|>|~参照する・上記の加算後から数値を取り出す。| |SIZE(22):&tt(){00000000001100100100010110001101}|RIGHT:3294605|ここから| |SIZE(22):&tt(){00000000000000111111100000000000}|RIGHT:260096|範囲*場所とANDで| |SIZE(22):&tt(){00000000000000100100000000000000}|RIGHT:147456|範囲以外を0にしたあと| |SIZE(22):&tt(){00000000000000000000100000000000}|RIGHT:2048|場所値で割り| |SIZE(22):&tt(){00000000000000000000000001001000}|RIGHT:72|数値を取り出す。| #endregion #region(''■bit分割Var用Var表・txtファイル用'') **■bit分割Var用Var表・txtファイル用 #aa(){;Var表用の32bit分割表 bit住所値付き ;Var(**)1 =(1) = ;--bit--2 =(2) = ;--bit--3 =(4) = ;--bit--4 =(8) = ;--bit--5 =(16) = ;--bit--6 =(32) = ;--bit--7 =(64) = ;--bit--8 =(128) = ;--bit--9 =(256) = ;--bit-10 =(512) = ;--bit-11 =(1024) = ;--bit-12 =(2048) = ;--bit-13 =(4096) = ;--bit-14 =(8192) = ;--bit-15 =(16384) = ;--bit-16 =(32768) = ;--bit-17 =(65536) = ;--bit-18 =(131072) = ;--bit-19 =(262144) = ;--bit-20 =(524288) = ;--bit-21 =(1048576) = ;--bit-22 =(2097152) = ;--bit-23 =(4194304) = ;--bit-24 =(8388608) = ;--bit-25 =(16777216) = ;--bit-26 =(33554432) = ;--bit-27 =(67108864) = ;--bit-28 =(134217728) = ;--bit-29 =(268435456) = ;--bit-30 =(536870912) = ;--bit-31 =(1073741824)= ;--bit-32(-2147483648)= ;範囲用 ;-bit-xx-xx=(&x範囲値x)/x場所値x= } #endregion //|&tt(){}|RIGHT:|| //|&tt(){}|RIGHT:|| //|&tt(){}|RIGHT:|| //|&tt(){}|RIGHT:|| ----

表示オプション

横に並べて表示:
変化行の前後のみ表示: