CodeGym /Kurslar /Java SELF AZ /Bit əməliyyatları, hissə 2

Bit əməliyyatları, hissə 2

Java SELF AZ
Səviyyə , Dərs
Mövcuddur

1. Bitlərin sola sürüşdürülməsi

Java-da da 3 rəqəmin bitlərinin sürüşdürülməsi üçün operator var. Lazım olduqda rəqəmin bütün bitlərini sola və ya sağa bir neçə mövqe sürüşdürmək çox asandır.

Rəqəmin bitlərini sola sürüşdürmək üçün sola bit sürüşdürmə operatoru-dan istifadə etmək lazımdır. Bu aşağıdakı kimi yazılır:

a << b

Burada, a — bitlərini sürüşdürdüyümüz rəqəm, b isə rəqəm a-nın bitlərini neçə bit sola sürüşdürmək lazım olduğunu göstərən rəqəmdir. Bu halda rəqəmin sağ tərəfinə sıfır bitləri əlavə olunur.

Nümunələr:

Nümunə Nəticə
0b00000011 << 1
0b00000110
0b00000011 << 2
0b00001100
0b00000011 << 5
0b01100000
0b00000011 << 20
0b001100000000000000000000

Bitləri bir mövqe sola sürüşdürmək rəqəmi 2-yə vurmaqla eyni effekti verir.

Rəqəmi 16-ya vurmaq istəyirsiniz? 16 = bu 24-dür. Bunun üçün rəqəmi 4 mövqe sola sürüşdürmək lazımdır.


2. Bitlərin sağa sürüşdürülməsi

Həmçinin bitləri sağa sürüşdürmək olar. Bunun üçün bitlərin sağa sürüşdürülməsi operatoru istifadə olunur. O belə yazılır:

a >> b

Burada, a — bitlərini sürüşdürdüyümüz ədəd, b — bu ədədin bitlərinin sağa nə qədər sürüşdürüləcəyini göstərən ədəd.

Nümunələr:

Nümunə Nəticə
0b11000011 >> 1
0b01100001
0b11000011 >> 2
0b00110000
0b11000011 >> 5
0b00000110
0b11000011 >> 20
0b00000000

Bitlərin sağa bir pillə sürüşdürülməsi eyni effekti verir ki, bu da ədədin 2-yə bölməsinə bərabərdir.

Bununla bərabər soldan ədədə sıfır bitlər əlavə olunur, amma həmişə deyil!

Vacibdir!

Ədədin ən sol biti işarə biti adlanır: əgər ədəd müsbətdirsə 0, mənfi olarsa 1 saxlamaq üçün istifadə olunur.

Ədədin bitləri sağa sürüşdürüləndə, işarə biti də hərəkət edir və ədədin işarəsi itir. Buna görə mənfi ədədlər üçün (ən sol biti 1 olan ədədlər) bu bit xüsusi olaraq saxlanılır. Ədədin bitləri sağa sürüşdürüləndə, ən sol biti 0 olarsa 0, ən sol biti 1 olarsa 1 ilə tamamlanır.

Amma yuxarıdakı nümunədə bu baş vermir. Niyə? Məsələ ondadır ki, tam ədədi literallar int tipindədir və 0b11111111, əslində, 0b00000000000000000000000011111111 deməkdir. Başqa sözlə, ən sol bit sıfıra bərabərdir.

Bir çox proqramçılar sağa sürüşdürmənin bu davranışına görə narahat olurlar və istəyirlər ki, ədəd həmişə sıfır bitlərlə tamamlanmalıdır. Buna görə, Java-da başqa bir sağa sürüşdürülmə operatoru əlavə etdilər.

O belə yazılır:

a >>> b

Burada, a — bitlərini sürüşdürdüyümüz ədəd, b — ədədin bitlərinin sağa nə qədər sürüşdürüləcəyini göstərən ədəd. Bu operator həmişə ədədin solunu sıfır bitlərlə tamamlayır, ədədin a-nın işarə biti nə olursa olsun.



3. Fləqlərlə işləmək

Bitlərlə əməliyyatlar və sürüşdürmə əməliyyatlarının əsasında proqramçılar tamamilə yeni bir istiqamət yaratdılar — fləqlərlə işləmək.

Kompyuterlərdə yaddaş çox az olduğu dövrlərdə, bir ədədə bir çox məlumatı sığışdırmaq çox populyar idi. Bu ədəd, bitlərdən ibarət bir massiv kimi nəzərə alınırdı: int — 32 bit, long — 64 bit.

Belə bir ədədə xüsusilə məntiqi məlumatları saxlamaq üçün çox şey yazmaq olar: true və ya false. Bir long 64 elementlik bir boolean massivinə bərabərdir. Bu cür bitlərə fləq deyilirdi və onların belə əməliyyatlara ehtiyacı var idi:

  • fləqi təyin et
    (müəyyən bir biti 1 etmək)
  • fləqi sıfırla
    (müəyyən bir biti 0 etmək)
  • fləqi yoxla
    (müəyyən bir bitin dəyərini yoxlamaq)

Və bunu bitlərlə operatorlarla necə etmək olar.

Fləqin təyin edilməsi

Müəyyən bir biti 1 etmək üçün, həmin biti dəyişdirəcəyimiz ədəd ilə xüsusi bir ədəd arasında, yalnız həmin bitin 1 olduğu əməliyyatı yerinə yetirməliyik.

Məsələn, sizə 0b00001010 ədədində 5-ci biti 1 etmək lazım olarsa, belə edə bilərsiniz:

0b00001010 | 0b00010000 = 0b00011010

Əgər 5-ci bit artıq 1 olmuş olsaydı, heç nə dəyişməzdi.

Ümumi halda, fləqin təyin edilməsini aşağıdakı kimi yaza bilərsiniz:

a | (1 << b)

Burada, a — müəyyən bir biti 1 edən ədəddir. b isə müəyyən edilmiş bitin indeksidir. Burada sola sürüşdürmə istifadə etmək əlverişlidir – hansı bit ilə işlədiyimiz dərhal aydın olur.

Fləqin sıfırlanması

Müəyyən bir biti 0 etmək, digərlərini isə dəyişmədən saxlamaq üçün, həmin biti 0 etmək istədiyimiz ədəd ilə xüsusi bir ədəd arasında & əməliyyatı yerinə yetirmək lazımdır. Bu xüsusi ədədə bütün bitlər 1, yalnız lazım olan bit 0 olur.

Məsələn, sizə 0b00001010 ədədində 4-cü biti 0 etmək lazım olarsa, belə edə bilərsiniz:

0b00001010 & 0b11110111 = 0b00000010

Əgər 4-cü bit artıq 0 olmuş olsaydı, heç nə dəyişməzdi.

Ümumi halda, fləqin sıfırlanmasını aşağıdakı kimi yaza bilərsiniz:

a & ~(1 << b)

Burada, a — müəyyən bir biti 0 edən ədəddir. b isə sıfırlanacaq bitin indeksidir.

Bütün bitləri 1, lazım olanı isə 0 edən ədədi əldə etmək üçün, biz əvvəlcə 1-i b mövqe sola sürüşdürürük və sonra isə bitləri bitlərlə NOT əməliyyatı ilə dəyişdiririk.

Fləqin yoxlanılması

Fləqin təyin edilməsi və ya sıfırlanması ilə yanaşı, bəzən yalnız fləqin təyin edilib-edilmədiyini yoxlamaq lazımdır – müəyyən bir bit 1-ə bərabərdir mi? Bu, bitlərlə & əməliyyatı ilə asanca həyata keçirilə bilər.

Məsələn, 0b00001010 ədədində 4-cü bitin 1 olub-olmamasını yoxlamaq istəyirsiniz. Bu halda, belə edə bilərsiniz:

if ( (0b00001010 & 0b00001000) == 0b00001000 )

Ümumi halda, fləqin yoxlanılması bu şəkildə yazıla bilər:

(a & (1 << b)) == (1 << b)

Burada, a — yoxlanılan bitin daxil edildiyi ədəddir. b isə yoxlanılan bitin indeksidir.


4. Şifrələmə

Bit səviyyəli XOR əməliyyatı tez-tez proqramçılar tərəfindən ən sadə şifrələmə üçün istifadə olunur. Ümumi halda şifrələmə əməliyyatı aşağıdakı kimi görünür:

nəticə = sayı ^ parol;

Burada sayı — şifrələmək istədiyimiz məlumatlar, parol — məlumatlara "parol" olaraq istifadə edilən xüsusi bir rəqəm, və nəticə — şifrələnmiş rəqəmdir.

sayı == (sayı ^ parol) ^ parol;

Bütün məsələ bundadır ki, XOR operatoru iki dəfə bir rəqəmə tətbiq edildikdə, paroldan asılı olmayaraq ilkin rəqəmi verir.

Şifrələnmiş sayıdan orijinal rəqəmi əldə etmək üçün sadəcə əməliyyatı təkrar etmək lazımdır:

orijinal sayı = nəticə ^ parol;

Nümunə:

class Solution
{
   public static int[] cript(int[] data, int password)
   {
     int[] result = new int[data.length];
     for (int i = 0; i <  data.length; i++)
       result[i] = data[i] ^ password;
     return result;
   }

   public static void main(String[] args)
   {
     int[] data =  {1, 3, 5, 7, 9, 11};
     int password = 199;

     // məlumat massivini şifrələyirik
     int[] encrypted = cript(data, password);
     System.out.println(Arrays.toString(encrypted));

     // məlumat massivini deşifrə edirik
     int[] decrypted = cript(encrypted, password);
     System.out.println(Arrays.toString(decrypted));
   }
}

Şərhlər
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION