Java Puzzle 05 – 0xcafebabe
Merhaba Arkadaslar,
Java’da tamsayilar icin 4 farkli literal mevcuttur.
- Binary ( 2lik)
- Octal ( 8lik)
- Decimal (10luk)
- Hexadecimal (16lik)
Java’da , hexadecimal sayilar 0X ya da 0x ile baslar.
- a/A 10
- b/B 11
- c/C 12
- d/D 13
- e/E 14
- f/F 15
Hex.java
package _05.cafebabe; public class Hex { public static void main(String[] args) { // hexadecimal literals start 0X or 0x // a/A 10 // b/B 11 // c/C 12 // d/D 13 // e/E 14 // f/F 15 System.out.println("Hexadecimal test"); System.out.println(0xa); System.out.println(0xB); System.out.println(0xC); System.out.println(0x10); System.out.println(0x123456); System.out.println(0xcafebabe); // -889275714 } }
Ornegimizi calistiralim ;
10 11 12 16 1193046 -889275714
Her sey yolunda giderken 0xcafebabe icin negatif cikti verdi. Burada dikkat edecek olursak sayilarimiz int tipinde. cafebabe hexadecimal sayisinin 16lik karsiligi int sinirinin disindadir.
http://www.binaryhexconverter.com/hex-to-decimal-converter
(cafebabe)16 = (3405691582)10
Decimal literallerin hepsi pozitiftir, negatif bir decimal literal sabiti icin , eksi(-) operatorunu kullaniriz. Bu durum octal ve hexadecimal literaller icin gecerli degildir. Bu literaller pozitif veya negatif olabilirler.
System.out.println("MAX_VALUE : " + Integer.MAX_VALUE); System.out.println("MAX_VALUE + 1 : " + (Integer.MAX_VALUE + 1)); System.out.println("MAX_VALUE + 2 : " + (Integer.MAX_VALUE + 2)); System.out.println("MAX_VALUE + 3 : " + (Integer.MAX_VALUE + 3));
Ciktiyi inceleyecek olursak Integer.MAX_VALUE -> 2147483647 -> 2^31 -1 degeridir.
Dikkat edecek olursak MAX_VALUE degerine +1 degeri ekledigimizde bu deger (-) MIN_VALUE degerine ulasmaktadir. Sirasiyla 2 , 3 ekledigimizde bu negatif degerler artmaktadir.
MAX_VALUE : 2147483647 MAX_VALUE + 1 : -2147483648 MAX_VALUE + 2 : -2147483647 MAX_VALUE + 3 : -2147483646
Bir baska ornek kod olarak :
System.out.println(Long.toHexString(0x100000000L + 0xcafebabe));
Ornegimizi calistirdigimizda sonucun 1cafebabe olmasini bekliyoruz ama sonucumuz cafebabe olacaktir. Peki sorun nerede ? 1.sayi icin “L” literalini kullandigimiz icin toplama islemi “long” a yukseltilecek , long 16 hex digit/basamak’a kadar izin vereek. Dolayisiyla burada overflow olmayacak ve problem teskil etmeyecek. (overflow durumunu bir onceki yazida incelemistik)
0xcafebabe sayimizin -889275714 oldugunu yazdirmistik. Toplama islemimiz sirasinda 0xcafebabe int degeri long degerine yukseltilir. Su hale gelir; 0xffffffffcafebabeL
Sayimiz 16 digit/basamaktir , long tipi 16 digit hex sayiya izin vermektedir. int ise 8 digit hex sayiya izin vermektedir.
System.out.println(0xffffffffcafebabeL); //-889275714 System.out.println(0xcafebabe); // -889275714
long degerine yukseltilen sayimiz ile toplama islemi gerceklestiginde asagidaki durum olacaktir.
0xffffffffcafebabeL 0x0000000100000000L + -------------------- 0x00000000cafebabeL
Bu sign extension problemini cozmek icin cafebabe sayimizi tanimlarken long literali seklinde tanimlamaliyiz.
System.out.println(Long.toHexString(0x100000000L + 0xcafebabeL)); //1cafebabe
Bu durumda sign extension problemi olmayacak ve islem sonucu dogru gosterilecektir.
0x00000000cafebabeL 0x0000000100000000L + -------------------- 0x00000001cafebabeL
Ozetlecek olursak;
Hex veya Octal literaller eksi (-) isaretine sahip olmadan da eksi(-) / negatif bir degere sahip olabilirler. 0xcafebabe ‘ de oldugu gibi.
Sign extension probleminden kacinmak farkli veri tiplerini birlikte kullanmayalim yapmayalim.
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
Leave a Reply