四則のサンビット算術演算(A)
ビット・コンピューティングは、我々だけに接触するコンピュータを学ぶために始めている一つのことであると言うことができます。そして、それは動作しません、我々はいくつかのショーを行うためにそれを使用できるかどうか、とても一般的な操作をビット?
使用事業者は、次の(存在しているのjava含ま>>>
符号なし右):
意味 | 演算子 | 例 |
---|---|---|
左(以下、0を補完します) | << | 0011 => 0110 |
右(先行ゼロ、正、負S.1) | >> | 0110 => 0011 |
ビットごとのOR | _ | 0011 ------- => 1011 1011 |
ビットAND | & | 0011 ------- => 1011 1011 |
ビット演算 | 〜 | 0011 => 1100 |
ビット単位のXOR(同様に、0から1まで異なります) | ^ | 0011 ------- => 1000年1011年 |
左から右シフト
右には、同等のほかにある左側に乗算に相当し、2倍一方を左、左、ポジティブ、ネガティブ、それらが右であるかどうか、ように4を乗じ2を残し、そしてシフトは、独自の符号なし32ビット右シフトされ、
四則演算とビット・コンピューティング(ここで考慮される整数[Javaバージョン])
追加
さらにそこに二つの動作は以下のとおりです。求和
と进位
合計:1 + 0 = 1 = 1 + 0 + 0 = 0
XOR:1 = 1 ^ 1 ^ 0 ^ 0 = 0 = 0 0 1
キャリー:1 + 1 + 1 = 1 + 0 = 0 0 = 0を
位与:1&1 = 1&0 = 0 0 0 0 =
したがって、この時間は、我々は確かに使う追加を達成するためにビット演算を使用异或
し、位与
-
再帰バージョン
// 使用递归实现 int add(int a,int b){ // 假如进位为0 if(b ==0){ return a; } // 获得求和位 int s = a^b; // 获得进位,然后需要向做移动一位表示进位 int c = ((a&b)<<1); return add(s,c); }
-
非再帰バージョン
再帰と非再帰バージョンは異なるバージョンではありません
int add2(int a,int b){ int s; int c; while(b != 0){ // 获得求和位 s = (a^b); // 获得进位,然后需要向做移动一位表示进位 c = ((a&b)<<1); a = s; b = c; } return a; }
引き算
減算、EMM、簡単なポイントは、単に負の数の追加を言い、やることに加えを使用することです、それ
まず、最初の被減数否定(で否定する必要があります~a+1
)
int adverse(int a){
return add(~a,1);
}
減算のための完全なコード
// 取得相反数
int adverse(int a){
return add(~a,1);
}
// 减法函数 其中add就是前面的加法函数
int subtract(int a,int b){
return add(a,adverse(b));
}
乗算
彼は前の乗算は私たちが最初のシンボルの下の問題を検討すると述べました。
まず第一に、の番号を知ってみましょうことは、正または負であります
// 负数返回-1,正数返回0
int getsign(int i){
return (i >> 31);
}
負の場合には、反転され
// 如果为负数,则进行取反
int toPositive(int a) {
if (a >> 31 == -1)
// 进行取反
return add(~a, 1);
else
return a;
}
-
解決策1:
乗算は、私たちの子供学習掛け算、教師はそれの和であるので、我々は確かに乗算を達成するためのオプションを使用することができ、このような* 7 6 7 6として、積和演算することで、私たちに語りました。O(N)の時間複雑。
int multiply(int a, int b){
Boolean flag = true;
// 如果相乘为正数,flag为false
if (getsign(a) == getsign(b))
flag = false;
// 将a取正数
a = toPositive(a);
b = toPositive(b);
int re = 0;
while (b!=0) {
// 相加
re = add(re, a);
// b进行次数减一
b = subtract(b, 1);
}
// 假如结果是负数,则进行取反
if (flag)
re = adverse(re);
return re;
}
-
ソリューション2
まず、それの写真を見て、私はタッチパッドのノートブックの絵を使用しているため、この絵は、醜い少し(ENが、私は醜いを我慢できない)、バイナリ画像は上記2 * 6乗算されます。
私たちが見ることができる上に、それはやや似掛け
与&
、それを運ぶことを除いて、。だから、私たちの問題を簡略化することができます。相は、その後、運ぶことができ、その後、合計します。最後のビットbはプラスすることができ、1であれば、右へ左へのシフト、Bの移動:私は方向を変更したいです。(時間複雑さO(LOGN))int multiply2(int a, int b) { Boolean flag = true; // 如果相乘为正数,flag为false if (getsign(a) == getsign(b)) flag = false; // 将a取正数 a = toPositive(a); b = toPositive(b); int re = 0; while (b!=0) { // 假如b的最后一位为1 if((b&1) == 1){ // 相加 re = add(re, a); } b = (b>>1); a = (a<<1); } // 假如结果是负数 if (flag) re = adverse(re); return re; }
除算
同様の除算と乗算。
-
ソリューション1
ソリューション1つの部門と同様のソリューションの乗算、マイナス上記の配当から除数、還元が十分でなくなるまで、ちょうどあきらめます。O(N)の時間複雑。
-
対処方法2は
2つのアイデア回避策このです:からb*(2**i)开始减
(2 **私は2のI乗を表し)、および削減されましたb*(2**0)
。そのようなソリューションの時間複雑度は、O(LOGN)です。// a/b int divide(int a,int b){ Boolean flag = true; // 如果相除为正数,flag为false if (getsign(a) == getsign(b)) flag = false; // 将a取正数 a = toPositive(a); b = toPositive(b); int re = 0; int i = 31; while(i>=0){ // 如果够减 // 不用(b<<i)<a是为了防止溢出 if((a>>i)>=b){ // re代表结果 re = add(re, 1<<i); a = subtract(a, (b<<i)); } // i减一 i = subtract(i, 1); } // 假如结果是负数 if (flag) re = adverse(re); return re; }
ここで[OK]をクリックし、今日の4ビットの演算、焦点は、ここで私は、アルゴリズムでショービットの算術演算のいくつかについて話します次のブログではありませんので、私は、アカウントへのデータのオーバーフローの場合を取らなかったところ。