2015-08-26 14 views
5

Sadece uint8_t dizilimimi uint64_t ile birleştirmek istiyorum. Aslında, problemimi çözdüm ama sebebini anlamak gerekiyor. İşte benim kodum; İstediğimi olduğunuNeden "uint8_t" yerine "uint64_t" * * sola kaydırma yapmalıyım?

uint8_t byte_array[5]; 

    byte_array[0] = 0x41; 
    byte_array[1] = 0x42; 
    byte_array[2] = 0x43; 
    byte_array[3] = 0x44; 
    byte_array[4] = 0x45; 

    cout << "index 0: " << byte_array[0] << " index 1: " << byte_array[1] << " index 2: " << byte_array[2] << " index 3: " << byte_array[3] << " index 4: " << byte_array[4] << endl; 

    /* This does not work */ 
    uint64_t reverse_of_value = (byte_array[0] & 0xff) | ((byte_array[1] & 0xff) << 8) | ((byte_array[2] & 0xff) << 16) | ((byte_array[3] & 0xff) << 24) | ((byte_array[4] & 0xff) << 32); 

    cout << reverse_of_value << endl; 

    /* this works fine */ 
    reverse_of_value = (uint64_t)(byte_array[0] & 0xff) | ((uint64_t)(byte_array[1] & 0xff) << 8) | ((uint64_t)(byte_array[2] & 0xff) << 16) | ((uint64_t)(byte_array[3] & 0xff) << 24) | ((uint64_t)(byte_array[4] & 0xff) << 32); 

    cout << reverse_of_value << endl; 

ilk çıkış "44434245" olacak ve ikincisi "4544434241" olacaktır. Bunun beni alakasız bir sonuç verir döküm kullanmak istemiyorsanız ben kod uint64_t için her bayt döküm kullandığınızda gördüğümüz Yani olarak

Ancak çalışır. Sebebini açıklayan var mı?

+1

Size 64 bit genişliğinde veri türüne upcasting önce-shift terk ettiğinde, bitleri sadece kayıp veya bozuk olsun olabilir. –

+0

's/olabilir ve/ErikAlapää @ 0 –

+1

: Hiç ihtiyacı; soru bir tane içerir. Ayrıca, bu bir "upcast" değil; Belirli bir terim istiyorsanız, bu "genişleyen bir dönüşüm" dir. –

cevap

6

sola kaydırır bir uint8_t birçok bit mutlaka işe gitmiyor. Soldaki işlenen, genişliğini bilmediğiniz int'a yükseltilecektir. Bu zaten olabilir 64-bit, ancak 32-bit veya hatta 16-bit olabilir, bu durumda & hellip; sonuç nereye giderdi? Bunun için yeterli yer yok! Kodunuzun daha sonra sonucu uint64_t'a getirmesi önemli değildir: ifade ayrı ayrı değerlendirilir.

doğru bir şekilde ikinci versiyonunda, önce uint64_tdönüştürerek sol değişimin söz konusu olduğunu tespit ettik. Bu durumda, ifade, istenen davranışa sahip olacaktır.

+2

7'den fazla bit, tamsayı tanıtılan sonuç değişkenine gider. Tam bir cevap tamsayı tanıtımına hitap etmelidir. 'In' 64 bit olduğunu varsayalım? Sonra kod sadece iyi çalışır. – Lundin

+1

Doğru değil. Bir vardiya operatörünün sol işleneni terfi ettirilir. Terfi edilen tür en az 16 bit olan "int" boyutudur. Yani evet, 'uint8_t' 7'den fazla bit (IN INT_BITS - 1' bit'ten daha az olduğu sürece) sola kaydırmak anlamlıdır. – ach

+0

Alrighty - daha iyi? –

2

İşte En azından benim makine, gcc 4.8.4, Ubuntu 14.04 LTS, x86_64 üzerinde yapar 0'a kömürü dönüm sol kaymasını gösteren bir örnektir.

#include <iostream> 

using std::cout; 

int main() 
{ 
    unsigned char ch; 

    ch = 0xFF; 

    cout << "Char before shift: " << static_cast<int>(ch) << '\n'; 
    ch <<= 10; 

    cout << "Char after shift: " << static_cast<int>(ch) << '\n'; 
} 

Not ayrıca yukarıda asıl soruya benim yorum, bazı platformlarda, 0x45 32 bit aslında 64 bit değerinin en az önemli bayt içinde biter kaymıştır.

+1

Hiç bir fikrim yok * Bu düzenleme nasıl onaylandı? Geri alındı. – Barry

+0

@Darvex: Önerilen düzenlemeleri incelediğinizde lütfen ** A LOT ** daha dikkatli olun. Onayladığınız kişi tamamen yanlıştı. –

İlgili konular