Java Puzzle 20 – Two’s complement

Merhaba Arkadaslar
Java da negatif sayilar nasil tutulur ? Right & Left Shifting operatorleri nasil calisir ?

Java da int veri tipi 32 bittir.

	int x = 1;
	// 00000000 00000000 00000000 00000001

Signed integer (32-bit) Two’s complement uzerinde Decimal to Binary olarak test edebilirsiniz.
<< operatoru ile sola bit kaydirma yapilir.
x<<1 icin bir kere sola kaydirma yapilir.

PositiveLeftShifting.java

	int x = 1;
	// 00000000 00000000 00000000 00000001
        // 1
	System.out.println(x << 1);
	// 00000000 00000000 00000000 00000010
        // 2^1
        // 2

Benzer sekilde 2 , 3 .. kere sola kaydirma islemi yapalim ;

	System.out.println(x << 2);
	// 00000000 00000000 00000000 00000100
        // 2^2
        // 4
	System.out.println(x << 3);
	// 00000000 00000000 00000000 00001000
        // 2^3
        // 8

Simdi de sinirlara dogru gidelim 30 kere sola kaydirma islemi yaparsak ;

        System.out.println(x << 30);
        // 01000000 00000000 00000000 00000000
        // 2^30
        // 1073741824

Peki bir kez daha sola kaydirirsak ne olur ? Javada negatif sayilar nasil gosterilir ?

	System.out.println(x << 31);
	// 1000000 00000000 00000000 00000000
	// -2^31
	// -2147483648

Java’da int veri tipi 32 bittir ve signed ozellik goster. Yani hem negatif deger hem pozitif deger alabilir. Bu mekanizma Two’s complement e gore calismaktadir.

32.bit 1 oldugu noktada bu sayi artik negatif bir sayidir. -2147483648 sayisi Integer.MIN_VALUE degerine esittir. Bu sayinin bir fazlasi ;

	// -2147483648+1 = -2147483647
	// 1000000 00000000 00000000 00000001

Peki sola kaydirma islemine devam edelim ;
Sayimiz tekrardan 1 ve 2 olacak.

	System.out.println(x << 32);
	// 00000000 00000000 00000000 00000001
	// 2^0
		
	System.out.println(x << 33);
	// 00000000 00000000 00000000 00000010
	// 2^1

PositiveRightShifting.java
>> operatoru de saga kaydirma yapacaktir. Ornegimizi inceleyelim;

public class BasicRightShifting {

	public static void main(String[] args) {

		int x = Integer.MAX_VALUE;
		// 01111111 11111111 11111111 11111111
		// 2147483647

		System.out.println(x);

		System.out.println(x >> 1);
		// 00111111 11111111 11111111 11111111
		// 1073741823

		System.out.println(x >> 2);
		// 00011111 11111111 11111111 11111111
		// 536870911

		System.out.println(x >> 3);
		// 00001111 11111111 11111111 11111111
		// 268435455

		System.out.println(x >> 4);
		// 00000111 11111111 11111111 11111111
		// 134217727
	}
}

Bekledigimiz gibi calismaktadir. Peki sinirlara gidecek olursak ;
31 kere right shifting yaptigimizda 0 a ulasiyoruz. Sonrasinda 1 kez daha shifting yaptigimizda tekrardan 2147483647 sayisina donus olmaktadir , yani sayinin kendisine donus olacaktir.

		System.out.println(x >> 31);
		// 00000000 00000000 00000000 00000000
		// 0

		System.out.println(x >> 32);
		// 01111111 11111111 11111111 11111111
		// 2147483647

Bir baska ornek olarak ;
y degiskenimiz 134216703 degerine sahiptir , bir kez right shifting yaptigimizda 67108351 degerine sahip olacaktir.
Kaydirma islemini nasil yaptigimizi anlamak icin bitlerin durumunu dikkatlice inceleyebilirsiniz.
Yine 31 kere right shifting yaptigimizda sayimiz 0 olacaktir , 32.kez shifting yaptigimizda ise tekrar eski haline donecektir.

		System.out.println("shifting y");
		int y = 134216703;
		// 00000111 11111111 11111011 11111111

		System.out.println(y);

		System.out.println(y >> 1);
		// 00000011 11111111 11111101 11111111
		// 67108351

		System.out.println(y >> 2);
		// 00000001 11111111 11111110 11111111
		// 33554175

		System.out.println(y >> 3);
		// 00000000 11111111 11111111 01111111
		// 16777087

		// 00000111 11111111 11111011 11111111
		// 00000011 11111111 11111101 11111111
		// 00000001 11111111 11111110 11111111
		// 00000000 11111111 11111111 01111111

		System.out.println(y >> 31);
		// 00000000 00000000 00000000 00000000
		// 0

		System.out.println(y >> 32);
		// 00000111 11111111 11111011 11111111
		// 134216703

Peki negatif sayilari inceleyelim simdi de ;

NegaiveLeftShifting.java

-1 degeri su sekilde ifade edilir ;
// 11111111 11111111 11111111 11111111
Ilk bastaki bit 1 oldugu icin sayinin negatif oldugu anlamina gelmektedir.
31 kere sola kaydirma yaptigimizda -2147483648 sayisina yani Integer.MIN_VALUE degerine ulasir.

32 kaydirma sonrasinda tekrar basa doner ve ayni sayi degerine sahip olur.

package _20.twos.complement;

public class NegativeLeftShifting {

	public static void main(String[] args) {

		// -1
		// 11111111 11111111 11111111 11111111

		System.out.println(-1 << 1);
		// -2
		// 11111111 11111111 11111111 11111110

		System.out.println(-1 << 2);
		// -4
		// 11111111 11111111 11111111 11111100

		System.out.println(-1 << 3);
		// -8
		// 11111111 11111111 11111111 11111000
		
		System.out.println(-1 << 30);
		// -1073741824
		// 11000000 00000000 00000000 00000000
		
		System.out.println(-1 << 31);
		// -2147483648
		// 10000000 00000000 00000000 00000000
		
		System.out.println(-1 << 32);
		// -2147483648
		// 11111111 11111111 11111111 11111111
	}
}

Saga kaydirma ornegini inceleyelim ;

-2147483648 degeri su sekilde ifade edilir ;
// 10000000 00000000 00000000 00000000

Saga kaydirma islemi yapiliyor , ilk bit negatif sayiyi temsil ediyor bu nedenle bu bit yine 1 olarak kaliyor.

31 kere saga kaydirdigimizda -1 degerine ulasmaktadir.

// -1
// 11111111 11111111 11111111 11111111

31 kere saga kaydirdigimizda tekrar basladigi yere donecektir.

// -2147483648
// 10000000 00000000 00000000 00000000

package _20.twos.complement;

public class NegativeRightShifting {

	public static void main(String[] args) {

		int min = Integer.MIN_VALUE;
		// -2147483648
		// 10000000 00000000 00000000 00000000

		System.out.println(min >> 1);
		// -1073741824
		// 11000000 00000000 00000000 00000000

		System.out.println(min >> 2);
		// -536870912
		// 11100000 00000000 00000000 00000000

		System.out.println(min >> 3);
		// -268435456
		// 11110000 00000000 00000000 00000000

		System.out.println(min >> 30);
		// -2
		// 11111111 11111111 11111111 11111110

		System.out.println(min >> 31);
		// -1
		// 11111111 11111111 11111111 11111111

		System.out.println(min >> 32);
		// -1
		// 10000000 00000000 00000000 00000000
	}
}

Yazimi burada sonlandiriyorum.
Herkese Bol Javali Gunler dilerim.
Be an oracle man , import java.*;
Levent Erguder
OCP, Java SE 6 Programmer
OCE, Java EE 6 Web Component Developer

Print Friendly, PDF & Email

Leave a Reply

Your email address will not be published. Required fields are marked *