Shiffting Operation

Başlatan robikod, 25 Haziran 2021, 09:15:08

robikod

Herkese merhaba aşağıdaki iki kod parçası aynı görünmekle beraber bana aynı sonuçları vermiyor.

    HexValueArray[0] = ((ConvertedHex & (0x00000000000000FF)));
      HexValueArray[1] = ((ConvertedHex & (0x000000000000FF00))) >> 8;      
      HexValueArray[2] = ((ConvertedHex & (0x0000000000FF0000))) >> 16;
      HexValueArray[3] = ((ConvertedHex & (0x00000000FF000000))) >> 24;
      HexValueArray[4] = ((ConvertedHex & (0x000000FF00000000))) >> 32;
      HexValueArray[5] = ((ConvertedHex & (0x0000FF0000000000))) >> 40;
      HexValueArray[6] = ((ConvertedHex & (0x00FF000000000000))) >> 48;
      HexValueArray[7] = ((ConvertedHex & (0xFF00000000000000))) >> 56;
      for(j = 0; j < 8; j++)
          {
            
    ValueBuffer[position + (j - 8)]=HexValueArray[j];
        
          }
Bu şekilde HexValueArrayi doğru bir şekilde alıyorken, aşağıdaki kodda sadece 4bytelık kısmını alabiliyorum.

for(j = 0; j < 8; j++)
{                                                               
     HexValueArray[j] = ((ConvertedHex & (0x00000000000000FF << (j * 8))) >> ((8 * j)));
     ValueBuffer[position + (j - 8)] = HexValueArray[j];
}

ConvertedHex = 0xAABBCCDDEE001122 ise son kodda HexValueArray olarak 22 11 00 EE 00 00 00 00 alıyorum. Sizce neden olabilir tamamen aynı kod gibi görünüyor.

Tagli

#1
0x00000000000000FFull şeklinde yaz. Literal ifade varsayılan olarak yeterli uzunlukta olmuyor anlaşılan ve kısa olduğu için çok kaydırınca sıfırlanıyor.

https://onlinegdb.com/6ExzzIQFd

Ekleme:

unsigned long long kullandığın derleyicide 8 byte'a karşılık geliyor mu emin değilim. Eğer yukarıda dediğim gibi çalışmazsa #include <stdint.h> ifadesi ile birlikte (uint64_t)0xFF şeklinde yaz:
Gökçe Tağlıoğlu

robikod

#2
Alıntı yapılan: Tagli - 25 Haziran 2021, 09:57:300x00000000000000FFull şeklinde yaz. Literal ifade varsayılan olarak yeterli uzunlukta olmuyor anlaşılan ve kısa olduğu için çok kaydırınca sıfırlanıyor.

https://onlinegdb.com/6ExzzIQFd

Ekleme:

unsigned long long kullandığın derleyicide 8 byte'a karşılık geliyor mu emin değilim. Eğer yukarıda dediğim gibi çalışmazsa #include <stdint.h> ifadesi ile birlikte (uint64_t)0xFF şeklinde yaz:


Anladım peki bu şekilde kullanmak verimli mi sizce? Başka türlü bu işlemi nasıl yapabilriz bit kaydırma olmadan?

Tagli

Tam olarak ne yapmaya çalıştığını anlayamadım. Elinde 8 byte'lık bir buffer var. Bunu başka bir buffer'ın belli bir bölümüne kopyalamaya çalışıyor gibisin. Sorunu biraz daha açarsan yardımcı olabilirim belki.
Gökçe Tağlıoğlu

robikod

Alıntı yapılan: Tagli - 25 Haziran 2021, 11:40:06Tam olarak ne yapmaya çalıştığını anlayamadım. Elinde 8 byte'lık bir buffer var. Bunu başka bir buffer'ın belli bir bölümüne kopyalamaya çalışıyor gibisin. Sorunu biraz daha açarsan yardımcı olabilirim belki.
Evet aynen o şekilde yapmaya çalışıyorum.1 ms interruptunda 40 kez 64 bytelık, 32 bytelık dataları bu şekilde 8 lik buffera atmam gerekiyor. Dolayısıyla hızlı bir şekilde yapabilmek benim için önemli. Bit kaydırma işlemiyle çok vakit kaybediyorum diye düşünüyorum o yüzden başka bir yöntemle yapabilir miyim diye bir arayıştayım.

 mesela elimde 64 bytelık veriler var bunları şu şekilde yapabiliyorum;
for(j = 0; j < 8; j++)
{
   ValueBuffer[propertyPosition + (j - 8)] = ((char*)&ConvertedHex)[j];
}
Bunun daha hızlı bir kod olduğunu düşünüyorum ancak bu kez, 32 bytelıklar için denediğimde bana geri dönen data hatalı oluyor.

for(j = 0; j < 4; j++)
{
   ValueBuffer[propertyPosition + (j - 4)] = ((char*)&ConvertedHex)[j];
}

Tagli

Byte'ların sıralarını değiştirmek gibi bir durum yoksa doğrudan memcpy kullan. Burada bit kaydırmalık bir durum yok. Bana sanki basit bir işi fazla karmaşık hale getiriyorsun gibi geldi.
Gökçe Tağlıoğlu

robikod

Alıntı yapılan: Tagli - 25 Haziran 2021, 14:31:04Byte'ların sıralarını değiştirmek gibi bir durum yoksa doğrudan memcpy kullan. Burada bit kaydırmalık bir durum yok. Bana sanki basit bir işi fazla karmaşık hale getiriyorsun gibi geldi.
Bytelerın sıraları önemli bir sonraki döngüde bufferın farklı pozisyonunu kullanabiliyorum.

Tagli

Sıranın ters dönmesi durumundan bahsediyorum. Yani byte'lar 1 2 3 4 diye gelmişse 4 3 2 1 oluyor mu mesele o. Eğer böyle bir ters dönme yoksa memcpy rahatlıkla kullanılabilir. Senin verdiğin örnekte böyle bir ters dönme var mı yok mu emin olamadım. Ama olsa bile, yine de bit kaydırma doğru yöntem değil. Üstelik kaydırmaya çalıştığın değerler 64-bit, bu seni daha da yavaşlatır.
Gökçe Tağlıoğlu

e-zeki

Bende bit kaydırmalık bir durum göremedim memcpy işinizi görüyor olması lazım.
eğer byte reverse durumu yoksa union kullanarak da çözebilirsiniz
union{
 uint64_t variable;
 uint8_t bytes[8];
}foo;

variable içine attığınız 64 bitlik değer, bytes array'ında doğrudan erişilebilir.
Ayrıca sebebini net olarak bilmiyorum ama ARM'da 32 bitten sonra bitshift yapmak mümkün değil. 32 ve üzeri shift yaptığınız anda üst 4 byte 0xFFFFFFFF olurken, alt 4 byte sıfırlanır.