ネガティブバイナリ表現-「闘争カップ」プログラミングコンテストトピック
0、タイトル
コンピュータの数字はすべてバイナリ表現です。実際、負のバイナリ表現があり、符号ビットは必要ありません。
たとえば、(-2)2 +(-2)1 +(-2)0 = 4-2 + 1 = 3であるため、3の負のバイナリ表現は111です。
別の例は、-3の負のバイナリ表現が1101である場合です。これは、(-2)3 +(-2)2 +(-2)0 = -8 + 4 + 1 = -3であるためです。
整数を入力し、その負のバイナリ表現を出力する必要があります。
- ゴラン
- Java
1.考える
パワー | 値 |
---|---|
0 | 1 |
1 | -2 |
2 | 4 |
3 | -8 |
4 | 16 |
5 | -32 |
表から、負のバイナリは理論的にはコンピュータの桁の範囲内の任意の整数値を表すことができることがわかります。
将来の使用のためにいくつかの特別な値を準備します、(0)10 =(0)-2、(1)10 =(1)-2、(-1)10 =(11)-2
まず、10進数を2進数に変換する方法を思い出してください。2で割り、残りを逆に書きます、ええと、最初に試してみて、負のバイナリ変換も使用できるかどうかを確認しましょう。
1.1最初に単純な値を試してください16
- 16 /(-2)=-8······0
- -8 /(-2)= 4······0
- 4 /(-2)=-2······0
- -2 /(-2)= 1······0
したがって、(16)10 =(10000)-2、まあ、それは問題ないようです。
1.2質問の語幹の値3を再試行します
- 3 /(-2)=-1······1
- -1 /(-2)= 0······-1
- -1 /(-2)= 0······-1
- ······
- -1 /(-2)= 0······-1
ええと、どのようにして無限ループになりましたが、前の特別な値(-1)10 =(11)-2によれば、3 /(-2)の商は-1であり、残りは1であると推定できるので、(3)10 =( 111)-2、それは行われているようです。
1.3特別な値を試す-13
最初にコードで-13 /(-2)を実行し、6の商と-1の残りを取得します。待って、残りは何ですか?残りは1または0であるべきではありませんか?もう一度考えてみてください。取得する必要のある商は7で、残りは1なので、これで終わりです。その後:
- -13 /(-2)= 7······1
- 7 /(-2)=-3······1
- -3 /(-2)= 2······1
- 2 /(-2)=-1······0
- -1 /(-2)= 1······1
したがって、(-13)10 =(110111)-2。
チェックしてください、(-2 )5 +(-2)4 +(-2)2 +(-2)1 +(-2)0 = -32 + 16 + 4-2 + 1 = -13。何も間違っていません!
結論として、配当が負で残りが-1の場合、計算された商は1増加する必要があり、残りは正になります1。
2goとjavaのコード実装
//go语言实现
func intToNegativeBinary(n int) {
if n == 0 {
fmt.Println(0)
return
}
const BASE = -2
var ans []byte
for n != 1 {
if n > 0 {
ans = append(ans, byte('0'+n%BASE))
n /= BASE
} else {
yu := n % BASE
if yu == -1 {
//余数为-1
n = n/BASE + 1
ans = append(ans, '0'+byte(1))
} else {
ans = append(ans, '0'+byte(yu))
n /= BASE
}
}
}
//把最后剩下的1加进去
ans = append(ans, '0'+byte(1))
length := len(ans)
//反转
for i := 0; i < length/2; i++ {
ans[i], ans[length-1-i] = ans[length-1-i], ans[i]
}
fmt.Println(string(ans))
}
//java代码实现
public static void intToNegativeBinary(int n){
if (n == 0){
System.out.println(0);
return;
}
int BASE = -2;
StringBuilder str = new StringBuilder();
while (n != 1){
if (n > 0){
str.append(n%BASE);
n/=BASE;
} else {
int yu = n%BASE;
if (yu == -1){
//余数为-1
n = n/BASE + 1;
str.append(1);
} else {
str.append(n%BASE);
n/=BASE;
}
}
}
//把最后剩下的1加进去
str.append(1);
str.reverse();
System.out.println(str);
}
Javaコードの場合、最初に追加してから逆にする代わりにstr.insert(0、1);を使用して、前面に追加することもできます。
私はそれを自分自身をテストした。このような10の大きさとして、大量のデータがある場合5が速く追加すると、次に逆になるように、両者の時間差は、近い20倍です。