>>> ve >> arasındaki fark


Yanıtlar:


408

>>aritmetik kaydırma sağ, >>>mantıksal kaydırma sağ.

Bir aritmetik kaydırmada, işaret biti sayının imzasını korumak için genişletilir.

Örneğin: 8 bitte temsil edilen -2 11111110(en önemli bit negatif ağırlığa sahip olduğu için) olacaktır. Aritmetik kaydırma kullanarak bir biti doğru kaydırmak size 11111111veya -1'i verir. Ancak, mantıksal sağ kayma, değerin imzalı bir sayıyı temsil edebileceğini umursamaz; her şeyi sadece sağa taşır ve soldan 0 saniye ile doldurur. Mantıksal kaydırma kullanarak -2 sağımızı bir bit kaydırmak verirdi 01111111.


8
Aritmetik kaymaların işaretli sayıları çarpmak için kullanılabileceğini kabul edip takdir etsem de2^k , bunun herkesin cevabı olduğunu garip buluyorum. Bir bit dizisi sayı değildir ve >>her zaman herhangi bir bit dizisinde kullanılabilir: bit dizisinin oynadığı rolden ve 'işaret' kavramına sahip olup olmadığına bakılmaksızın her zaman aynı şeyi yapar. Senin işlenen olduğunda Tamam durumda bir tartışma ile zaten büyük bir cevabı uzatmak olurdu değil imzalı sayı olarak yorumlanır ediliyor? Şikayetim mantıklı mı?
Ziggy

11
Neden bir bit dizisinin sayı olmadığını söylüyorsun? Ondalık basamak dizisinin sayı olmadığını söyleyebilir misiniz?
danben

4
@danben Bir sayı olup olmadığını tartışmak, onu bir bağlama bağlarsanız mantıklı olur. İnternet sadece elektrik ise, o zaman bir dize sadece bir sayı olduğunu kabul ediyorum.
bvdb

1
@danben ama aslında, Ziggy'nin gerçekten bahsettiği şey (imho), a'nın Stringda olarak kabul edilebileceğini düşünüyorum char[]. A'nın charbir sayı olmadığını söylemiyor ; sadece imzasız bir sayı olduğunu söylüyor . Bence burada kayboldu.
bvdb

5
@Ziggy doğru: Her bit dizisi bir sayı değildir ve her ondalık basamak dizisi bir sayı değildir. Örneğin: Telefon numaraları, posta kodları (birçok ülkede) vb. Ondalık basamak dizeleridir, ancak bunları eklemek, çıkarmak veya çarpmak mantıklı değildir, bu yüzden gerçekte sayılar değildir. Ondalık basamak dizeleri olurlar, ancak karakter dizeleri olarak ele alınmalıdırlar. (Kanada ve İngiltere'deki posta kodları harf ve rakam içerir.)
jcsahnwaldt diyor GoFundMonica

102

>>>imzasız kaydırma; 0 ekler >>ve imza biti eklenir.

JLS 15.19 Vardiya Operatörleri

Vardiya operatörleri arasında sola kaydırma <<, imzalı sağa kaydırma >>ve imzasız sağa kaydırma bulunur >>>.

Değeri n>>solan ndoğru kaydırılmış sbit pozisyonları işaret uzatma .

Değeri n>>>solan ndoğru kaydırılmış sbit pozisyonları sıfır uzatma .

    System.out.println(Integer.toBinaryString(-1));
    // prints "11111111111111111111111111111111"
    System.out.println(Integer.toBinaryString(-1 >> 16));
    // prints "11111111111111111111111111111111"
    System.out.println(Integer.toBinaryString(-1 >>> 16));
    // prints "1111111111111111"

Olumlu karşılık ekleyerek işleri daha net hale getirmek için

System.out.println(Integer.toBinaryString(121));
// prints "1111001"
System.out.println(Integer.toBinaryString(121 >> 1));
// prints "111100"
System.out.println(Integer.toBinaryString(121 >>> 1));
// prints "111100"

Olumlu olduğu için hem imzalı hem de imzasız vardiyalar en bitin başına 0 ekler.

İlgili sorular


Örnekleriniz olmasaydı, anlayamazdım.
mr5

47

İkisi de doğru kaydırma, ama >>>birunsigned

Gönderen belgeler :

İmzasız sağ kaydırma operatörü ">>>" sıfırı en soldaki konuma kaydırırken, ">>" işaretinden sonraki en soldaki konum işaret uzantısına bağlıdır.


12
bir örnekle açıklayabilir misiniz
Kasun Siyambalapitiya

1
Ben de bir örnek vermeniz gerektiğini düşünüyorum.
byxor

Sanırım bu >>>imzasız, ama neden 7>>32=7? Her seferinde bir vardiya yapan bir döngü çalıştırdım ve 32vardiyalardan sonra geri döndüğünü gördüm 7. Bunun mantıklı olabilmesinin tek yolu, kaydırılan her sayı için bir "dış çember" girmesidir. 32Vardiyalardan sonra , bir şekilde konumuna geri döndü, ancak açıkçası hala mantıklı değil. Ne oluyor?
Ian Limarta

@IanLimarta Değil mi? 0. (Sadece almak for (int i = 7 << 1, j = 0; j < 32; j++) System.out.println(Integer.toString(i >>= 1, 2));neden bahsediyorsan) >>32kendisi orijinal değerini verir, bkz bu .
Moira

Üzgünüm. Neden '7 >>> 32 = 7' demek istedim.
Ian Limarta

40

Mantıksal sağ kaydırma ( v >>> n), bitlerin bit konumlarıyla vsağa kaydırıldığı nve 0'ların sol taraftan kaydırıldığı bir değer döndürür . İkili olarak yazılan 8 bitlik değerleri kaydırmayı düşünün:

01111111 >>> 2 = 00011111
10000000 >>> 2 = 00100000

Bitleri imzasız negatif olmayan bir tamsayı olarak yorumlarsak, mantıksal sağ kaydırma, sayıyı karşılık gelen 2'ye bölme etkisine sahiptir. Ancak, sayı ikinin tamamlayıcı gösteriminde ise, mantıksal sağ kaydırma negatif sayıları doğru şekilde bölmez . Örneğin, üstteki ikinci sağ kaydırma, bitler işaretsiz sayılar olarak yorumlandığında 128'den 32'ye kayar. Ancak, Java'da olduğu gibi, bitler ikinin tamamlayıcısı olarak yorumlandığında -128'den 32'ye kayar.

Bu nedenle, iki güce bölmek için kaydırıyorsanız, aritmetik sağ kaydırmayı ( v >> n) istiyorsunuz . İçindeki bitlerin bit konumlarına vgöre sağa kaydırıldığı nve en soldaki v bitinin kopyalarının sol taraftan kaydırıldığı bir değer döndürür :

01111111 >> 2 = 00011111
10000000 >> 2 = 11100000

Bitler ikinin tamamlayıcı gösteriminde bir sayı olduğunda, aritmetik sağa kaydırma iki güçle bölme etkisine sahiptir. Bu en soldaki bit işaret biti olduğu için çalışır. İki güçle bölmek işareti aynı tutmak zorundadır.


38

>>>en soluna her zaman 0 >>koyar, işaretinin ne olduğuna bağlı olarak 1 veya 0 koyar.


10

Bitwise ve Bit Shift Operatörleri hakkında devamını oku

>>      Signed right shift
>>>     Unsigned right shift

Bit örüntüsü sol taraftaki işlenen tarafından ve sağ taraftaki işlenen tarafından kaydırılacak konum sayısı ile verilir. İmzasız sağ kaydırma operatörü sıfırı en soldaki konuma >>> kaydırır ,

en soldaki konum >>ise işaret uzantısına bağlıdır.

Basit bir deyişle >>>, her zaman , bir kayar sıfır soldaki pozisyona ise >>sayısının işaretini göre kaymalar pozitif bir sayı için negatif bir sayı için 1 ve 0, yani.


Örneğin, negatif ve pozitif sayılarla deneyin.

int c = -153;
System.out.printf("%32s%n",Integer.toBinaryString(c >>= 2));
System.out.printf("%32s%n",Integer.toBinaryString(c <<= 2));
System.out.printf("%32s%n",Integer.toBinaryString(c >>>= 2));
System.out.println(Integer.toBinaryString(c <<= 2));

System.out.println();

c = 153;
System.out.printf("%32s%n",Integer.toBinaryString(c >>= 2));
System.out.printf("%32s%n",Integer.toBinaryString(c <<= 2));
System.out.printf("%32s%n",Integer.toBinaryString(c >>>= 2));
System.out.printf("%32s%n",Integer.toBinaryString(c <<= 2));

çıktı:

11111111111111111111111111011001
11111111111111111111111101100100
  111111111111111111111111011001
11111111111111111111111101100100

                          100110
                        10011000
                          100110
                        10011000

Teşekkürler. Sadece Integer.MAX_VALUE, Integer.MIN_VALUE, -1, 0, 1 için bit temsiline başvurmak üzere bir yorum eklemek istersiniz . örneğin System.out.println(Integer.MAX_VALUE + ": " + String.format("%32s", Integer.toBinaryString(Integer.MAX_VALUE)).replace(' ', '0')):; Tamsayı.MAX_VALUE : 01111111111111111111111111111111; Tamsayı.MIN_VALUE :10000000000000000000000000000000; -1 : 11111111111111111111111111111111; 0 : 00000000000000000000000000000000; 1 : 00000000000000000000000000000001
Andy Dong

6

Sağ kaydırma mantıksal işleci ( >>> N) bitleri N konumuna göre sağa kaydırır, işaret bitini atar ve N en soldaki bitleri 0'larla doldurur. Örneğin:

-1 (in 32-bit): 11111111111111111111111111111111

bir >>> 1operasyondan sonra:

2147483647: 01111111111111111111111111111111

Sağ kaydırma aritmetik işleci ( >> N) de bitleri N konumuna göre sağa kaydırır, ancak işaret bitini korur ve N en soldaki bitleri 1'lerle doldurur. Örneğin:

-2 (in 32-bit): 11111111111111111111111111111110

bir >> 1operasyondan sonra:

-1: 11111111111111111111111111111111
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.