Döngüsel (rotary/circular) kaydırma işlemi, bir sayının bitlerinin belirli bir sayıda basamağa kaydırılması ve "düşen" bitlerin karşı tarafa taşınmasıdır. C dilinde bu görev için yerleşik bir operatör yoktur; bu durum tarihsel olarak standart kütüphanenin taşınabilirliği ve farklı platformlar için davranışı açıkça tanımlama gerekliliği ile ilgilidir.
Sorun, standart kaydırma operatörlerinin (<<, >>) kaydırmayı döngüsel hale getirmemesidir: sadece bitleri kaydırır ve "düşen" bitleri sıfırlarla değiştirir. Döngüsel kaydırma için, iki kaydırmanın sonuçlarını açıkça birleştirip sonucu belirtilen bit sayısı ile maskelemek gerekir.
Çözüm, döngüsel kaydırmayı manuel olarak uygulamaktır. 32 bitlik unsigned bir sayı için bu şöyle görünür:
uint32_t rotate_left(uint32_t value, unsigned int shift) { return (value << shift) | (value >> (32 - shift)); } uint32_t rotate_right(uint32_t value, unsigned int shift) { return (value >> shift) | (value << (32 - shift)); }
Anahtar özellikler:
<< veya >> operatörü ek işlemler olmadan döngüsel kaydırma gerçekleştirebilir mi?
Hayır. Normal kaydırmalar, dışarıda kalan basamakları sıfırlarla değiştirir, diğer tarafa taşımaz.
Bir kaydırma, türün boyutuna (şift'in sayıdaki bit sayısına) eşit olduğunda ne olur?
Davranış tanımsızdır (C standardına göre Undefined Behavior), kaydırmayı kesinlikle türün boyutuna göre almak gerekir.
Signed türler için bu fonksiyonlarla güvenli bir rotary kaydırma yapılabilir mi?
Hayır, her zaman unsigned türler kullanın, çünkü signed türlerin bit kaydırma işlemi derleyici ve mimariye bağlı olarak farklı davranır.
Döngüsel kaydırma için normal kaydırma kullanımı:
uint32_t x = 0xFA3C0F00; uint32_t y = x << 5; // Döngüsel bir özellik taşımıyor
Artıları:
Eksileri:
Türün boyutunu dikkate alarak ve UB'den koruma ile manuel rotary kaydırma fonksiyonunun kullanımı:
uint32_t x = 0xFA3C0F00; uint32_t y = rotate_left(x, 5);
Artıları:
Eksileri: