あなたは本当にまだビット演算を見つけますか?例えばJavaの、要約するために、

ビットコンピューティングは、ビット・コンピューティングによって、実際のコンピュータ演算に最も近いが、我々は効率的に、我々はまた巧妙なビット演算を使用することができます基本的な操作(加算、減算モジュロ、など)の様々なを完了することができ、非常に複雑なタスクを完了した、本当に理解していますコンピュータは、私たちはより良いコンピュータを使用することができます。私はJavaでいくつかの実用的なアプリケーションを説明するために、基礎を理解することから始めます。、•元のコードに基づいてコンテンツを学ぶ反転、などなどの補完またはおよび•負のシフトオペランドXOR演算の詳細を取り戻すだろう、この分野でのチャット•符号桁を計算します

EDITORIAL

ビットコンピューティングは、ビット・コンピューティングによって、実際のコンピュータ演算に最も近いが、我々は効率的に、我々はまた巧妙なビット演算を使用することができます基本的な操作(加算、減算モジュロ、など)の様々なを完了することができ、非常に複雑なタスクを完了した、本当に理解していますコンピュータは、私たちはより良いコンピュータを使用することができます。この1回の記事では、私はJavaでいくつかの実用的なアプリケーションを説明するために、基礎を理解することから始めます。

マシンの数とマシンの数真の値

コンピュータ表現で2進数が、マシンの数は、数と呼ばれます。機体番号は、マシンに格納されているシンボルの最大数、0の正の数、負の数と、コンピュータに、署名されます。例えば、機械の8ビットワード長の場合のように(機械語は、コンピュータの計算の精度を決定するコンピュータ処理に直接バイナリデータのビット数が、8の一般的に整数倍、8、16でありますビット、32ビット、64ビット、128ビット)-3がバイナリ10000011に変換された場合、小数+3は、バイナリ0000 0011に変換されます。00000011と10000011のバイナリ変換は、マシンの数です。

値の形式でマシンの数は、真の値と等しくないので、ここでは、我々はまた、真の価値を知っておく必要があり、マシンの最初の数字のためにマシンの数は、符号ビットです。区別のために、署名されたので、ことを上記マシンはシンボルの数を有する、例えば、最上位ビット負を表す番号10000011は、その実際の値は-3、代わりの値として131(DEC 131に10000011に等しいです)、これは、マシンの真の値に対応する実値となります。そのような真の値= + 000 = 0001 0000 0001 0001 +1,1000真値= -1 = -0000001

基本的な概念と、元のコードの方法、及び抗補コード

我々は二進数であるマシンの数が、特定の符号化方式を使用して格納されるコンピュータを理解の上、オリジナルコード、アンチコードと相補コードは、マシン固有のデジタル符号化に格納されています。

オリジナルコード

もし、8ビットバイナリ:元のコードは、符号ビットを加えた真の値の絶対値のような、すなわち、残りのビットが値を表す表す最初のシンボルです。

[+1] = 0000 0001オリジナル

[-1] = 1000 0001オリジナル

最初のビットは符号ビットであるようにレンジが8ビットのバイナリ:(最初に示していない、すなわち値であるので、最初のものは、符号ビットであり、唯一の正および負言う。)[11111111、01111111]、及び小数である[-127、127](ビープ音が静かに、実際には、署名付オリジナルマシンコードの数であると言うことができます)。

反転

陽性抗コードが独自で、元のコードの基礎である反転負の符号ビットを変更し、各ビットは静止するように反転されます。

[L] = [0000 0001]オリジナル= [0000 0001]トランス

[-1] = [1000 0001]オリジナル= [1111 1110]トランス

補数

補数表現は、元のコードに基づいており、独自の、負の補数を補完することを正の数は、あなたの残りの部分は、(最終的には+1、否定、そのまま、符号ビットで、その抗コードがあること1に基づきます)

[L] = [0000 0001]オリジナル= 0000 0001]トランス= 0000 0001】補

[-1] = [1000 0001]オリジナル= [1111 1110]トランス= [1111]補完

あなたはこれらの3の基本的な概念を知ったら、また、反転している場合、我々は補完を使用して、シンボルを修復するだけでなく、問題(-0 0)二つのゼロを引き起こし、という0言及する価値がありますそして2つの符号化の問題が存在するだけでなく、最小の数よりも多くを表現します。抗範囲[-127、+127]で表される元のコードまたはコードを使用して8ビットのバイナリが、表現範囲[-128、127]を補完するために使用された理由です。32ビットのint型は、一般的に表すことができる署名されたプログラムで使用されるように、マシンの補数ので、次のとおり符号ビットが最初に、補数表現で表されているように[-231は、231-1]が使用される場合あなたは、最小値よりも多くを保存することができます。

Javaでの演算子

、次の操作の全てのビットが補数によって実行されることに留意されたいが、補数は、自身に対応する負の数は、両方のオペランドがあれば、その結果バイナリ小数点直接アクセス陽性である自体が正である2前記オペランドは、結果が1(即ち、負)であれば、補体が得られる負の数または両方負、符号ビットであり、元のコードを補完する必要性は、小数に変換し、その場合符号ビットは0、バイナリ転送に小数への直接アクセスです。これは、操作がちょうど陰性となり、結果はすべての否定、元を取ることです補完されます。あなたはすべてのバイナリ補数に変換進数の下に身を置き、その後、正しい結果ではありませんを見て、数を考慮に入れることができます。

排他的論理和演算は、シンボル「^」、同じことが0である、1であり、例えば、以下のコード、異なっています。

public static void main(String[] args) {    System.out.println("2^3 运算的结果是 :"+(2^3));    //打印的结果是:   2^3 运算的结果是 :1}//2 的二进制 0010,3 的二进制 0011,2^3 就为 0001,结果就是 1public static void main(String[] args) {    System.out.println("-2^3 运算的结果是 :"+(-2^3));    //打印的结果是:   -2^3 运算的结果是 :-3}//-2 的二进制补码 1110,3 的二进制 0011,-2^3 就为 0001,结果就是-3

それであれば0に0があるように、コード例は、以下のように、「&」算術符号です。

public static void main(String[] args) {     System.out.println("2&3 运算的结果是 :"+(2&3));     //打印的结果是:   2&3 运算的结果是 :2}public static void main(String[] args) {     System.out.println("-2&3 运算的结果是 :"+(-2&3));     //打印的结果是:   -2&3 运算的结果是 :2}

:限りがあるので、1対1、コード例では、次のように、「|」であるか、演算子

public static void main(String[] args){    System.out.println("2|3 运算的结果是 :"+(2|3));    //打印的结果是: 2|3 运算的结果是 : 3}public static void main(String[] args){    System.out.println("-2|3 运算的结果是 :"+(-2|3));    //打印的结果是: -2|3 运算的结果是 : -1}

非オペレータは、例えば、次のコード、「〜」あなたを否定されています。

public static void main(String[] args){    System.out.println("~5 运算的结果是 :"+(~5));    //打印的结果是: ~5 运算的结果是 : -6}public static void main(String[] args){    System.out.println("~(-5)运算的结果是 :"+(~(-5)));    //打印的结果是: ~(-5)运算的结果是 : 4}

変位左向き記号「<<バイナリのnビットは、バックゼロで埋め、左にシフト

public static void main(String[] args) {     System.out.println("2<<3 运算的结果是 :"+(2<<3));     //打印的结果是:   2<<3 运算的意思是,向左移动 3 位,其结果是 :16}public static void main(String[] args) {     System.out.println("-2<<3 运算的结果是 :"+(-2<<3));     //打印的结果是:   -2<<3 运算的意思是,向左移动 3 位,其结果是 :-16}

変位右向き記号「>>」、nビットのバイナリ右シフト、値が正であれば値が負の場合、0は、ハイレベルに挿入され、1がハイに挿入され

public static void main(String[] args) {     System.out.println("2>>3 运算的结果是 :"+(2>>3));     //打印的结果是:   2>>3 运算的意思是,向右移动 3 位,其结果是 :0}public static void main(String[] args) {     System.out.println("-2>>3 运算的结果是 :"+(-2>>3));     //打印的结果是:   -2>>3 运算的意思是,向右移动 3 位,其结果是 :-1}

符号ビットを無視し、符号なし右シフト記号「>>>」、0空孔が充填されています。「>>>」と「>>」が唯一の違いは、それが何でオリジナルの左端の番号であり、すべてがゼロで満たされています。例えば、8ビットバイト、タイプバイト-1 11111111(補数表記)bと表さ>>> 4の符号なし右シフトが4である、すなわち、00001111は、この結果は15です。(私は符号なしの残っていた場合は静かにビープ音が、私に聞かないでください、とそうあなたは本当に熟達、あなたはこれが非常に低い問題があるでしょう。)

public static void main(String[] args) {     System.out.println("16>>2 运算的结果是 :"+((16)>>2));     //打印的结果是:   16>>2 运算的结果是 :4}public static void main(String[] args) {     System.out.println("-16>>2 运算的结果是 :"+((-16)>>2));     //打印的结果是:   -16>>2 运算的结果是 :-4}public static void main(String[] args) {     System.out.println("16>>>2 运算的结果是 :"+((16)>>>2));     //打印的结果是:   16>>>2 运算的结果是 :4}public static void main(String[] args) {     System.out.println("-16>>>2 运算的结果是 :"+((-16)>>>2));     //打印的结果是:   -16>>>2 运算的结果是 :1073741820}

乗算、除算、乗算と除算をカウントしないでください。

追加

13 + 9は、例えば、我々は、この演算処理を分割するように:

  • ステップ:キャリー・ビットを考慮していない、それぞれ、各桁の加算された結果は、合計として格納され、プラスの数字9 3 2であり; 1プラス10桁0〜1;最終結果は12です。
  • ステップ2:のみキャリービットを考慮して、結果は、キャリーとして格納3 + 9キャリーがあるされ、キャリーは10です。
  • ステップ3は:バイナリキャリーを得ステップ2の結果が0でない、そして合計がステップでキャリーを得られた二段階を取得した場合、繰り返しは、1つ、2つ、3つのステップ。キャリーの端部が0であれば、最終結果は、ステップ和を求めます。

実際には、これは、3つのステップの上方= 12とキャリー= 10の反復合計であります

  • 和の各桁のために、それぞれ、キャリービットを考慮せずに(A)、合計= 22。
  • (B)のみキャリービットを考慮した:ステップは、上で運ばない、キャリー= 0;(c)工程2carry = 0は、最終的な結果は、総和= 22です。

これは、2進数、10進数における当社事業のデモンストレーションであり、我々が交換されていないことがわかり、バイナリ13は、0000 1101,9 0000バイナリです:1001

  • ステップ:0100 = 0000 1101 0000 + 1001 = 0000合計の桁ごとに、それぞれ、キャリー・ビットを考慮しない、和
  • ステップ2:キャリービットを考慮して、2つの2進ビット0があると結果のみのキャリービットを考慮して、3ビットはである:キャリー0010 = 0001
  • 第三段階:キャリー== 0、ゼロでない、繰り返しステップ一つ、二つ、三つ、0端、結果が合計であります?。

本実施形態における

  • キャリービット和= 0001 0110を考慮せずに、
  • 唯一のキャリービットキャリー= 0を考えます。
  • キャリー== 0は、最終的な結果は、0110 = 0001合計であります

22は、単に10進数に変換されます。実際には、3つのステップが、疑似コード画像は、3 + 9と、例えば、次のように理解すべきです。

a = 0011, b = 1001;    start;    first loop;    1.1 sum = 1010    1.2 carry = 0010    1.3 carry != 0 , go on;    second loop;    2.1 sum = 1000;    2.2 carry = 0100;    2.3 carry != 0, go on;    third loop;    3.1 sum = 1100;    3.2 carry = 0000;    3.3 carry == 0, stop; result = sum;end
//1、递归形式实现int add(int a ,int b){    if (b == 0)        return a;    else{        int carry = (a & b) << 1;        a = a ^b;        return add(a,carry);    }}//非递归形式实现int add2(int a ,int b){   int carry;   while (b != 0){   carry = (a & b) << 1;       a = a ^b;       b = carry;   }   return a;}

引き算

私たちは、ビット操作が比較的簡単で、より少ない加算演算、減算を達成するために知っています。我々は、変形11--6当然、我々は減算思うであろう、加算器11 +を(-6)加算演算を実現する、すなわち正の数と負。コンピュータが加算減算それのように、同じことを達成していない理由はい、非常に巧妙な、実際には、私たちのコンピュータ操作は、あまりにも、一部の人は言うだろうということ?右、達成することがより困難と仮定することは合理的であるが、複雑なことに加えより減算を考えます。なぜ?私たちは、現在位置が減算が高いボローからそれを差し引く行うのに十分でない場合は、減算操作は、行われますのみ、キャリーが2つの操作を追加し、プラスされていることを知っている、と減算を行い、問題があるでしょう、ボローがどのように表現しますそれは?加算演算は、持ち運びや操作によって達成するものを左に、そして本当に悪いショーを借ります。だから私たちは自然に加えに減算を有効にすると思います。どのようにそれを達成するには?

私達はちょうど減算が、我々が最初にどのように表現されるか、負の数のコンピュータで見なければならないことを、正の数プラスマイナスの数値に変換することができました。

バイナリで1000コンピュータでは8、それは表し-8どのように?正の数を示すために0に等しい符号ビットのバイナリ桁(ビット)特別規定することができ、負の数の場合は1に等しい、と考えることは容易です。例えば、8ビットマシン、所定の最上位ビットは、各バイトの符号ビットです。だから、8は00001000で、-8 10001000です。それは実際には、コンピュータは2の補数(同じ補数は、英語が2の補数である、実際には、の2の補数として翻訳されなければならない)されているもの、それを否定を表すために、2の補数である、ただ直感的な表現ですか?これは、実施形態はまた、可変数、取得ステップの数の符号の符号付き数のバイナリ表現です。

  • 最初のステップは、各ビットが逆の値をとっている、0(すなわち、反転)0 1,1なるなります。
  • 第二工程は、前工程で得られた値(反転)プラス1。

単に否定プラスです!

int subtraction(int a ,int b){     b = ~b+1;     return this.add(a,b); }

乗算

私たちは、現実の生活マニュアル製品を求めているのプロセスは、このアプローチはまた、バイナリに適用を検討し、ここで私が13 * 14で午前、例えば、我々は、乗数の絶対値を検索し、手動計算を乗じた被乗数する方法を示します。ダイヤグラム最終結果に追加された現在の乗数ビットが1である場合、被乗数の結果をとり、グラフ計算処理から分かるように、左、現在のビットが0の場合、0に取るために製品に添加される(プラス0)何もしない、あります

  • 乗算係数がステップ0(4)に進み、0であるかどうかを決定します
  • 及び終了ビットを計算し、決定するための乗算器は、現在の被乗数の数の和次いで、1ならば、0または1であり; 0の場合、合計は0であり、最終的な数に加算結果;
  • 被乗数は、一つを左、右の乗算器;ステップに戻って(1)
  • 符号ビット出力を決定します。
      //a 被乘数,b 乘数      int multiplication(int a,int b){          int i = 0;          int res = 0;          //乘数不为 0          while (b != 0){              //处理当前位              //当前位是 1             if ((b & 1) == 1){                 res += (a << i);                 b = b >> 1;                 //记录当前是第几位                 i++;             }else {                 //当前位是 0                 b = b >> 1;                 i++;             }         }         return res;     }

除算

分割容易に起こるが、除数が除数より小さくなるまで被除数を除数を減算することによって維持され、減算、に変換することができ、周波数は、我々は商必要この時点で減少し、配当が時間である場合、残り。同じ剰余と被除数の符号、符号、記号および商業的に乗算の決意は、積の符号、すなわち、カード番号を被除数と除数に応じて、負の数が異なるように決定されることに留意されたいです。、すべてのデータがintをバイナリコンピュータの世界を使用することができる[2 ^ 0、2 ^ 1、...、2 ^ 31]基(INT-最大31)のグループを表現します。保存した場合、追加のそれぞれの複数のプロバイダに入れて、その下に移動すれば、配当を削減しようとする、...、除数31.2 ^ ^ 2 30の^ 0 ^ 2 2,2 ^ 1,2回は考えにくいです動かない、そして小さな倍数をオンにしてみてください。だから、すぐに最終結果に近づいてすることができます。

実際のパワーに2は、私は31なぜそれを開始するから、iビット相当を残しましたか?データint型の最大値は2 ^ 31ああされるからです。

    int division(int a,int b){          int res;          if(a<b){              return 0;          }else{              res=division(subtraction(a, b), b)+1;          }          return res;     }

続きを読む:http://gitbook.cn/gitchat/activity/5e46135165ec7013893ec3ba

また、CSDNコミュニティの品質のオリジナルコンテンツGitChatアプリをダウンロードするよりGitChat排他的な技術的な内容ああを読むことができます。

FtooAtPSkEJwnW-9xkCLqSTRpBKX

リリース3634元の記事 ウォンの賞賛3487 ビュー325万+

おすすめ

転載: blog.csdn.net/valada/article/details/104321752