2016-04-14 19 views
6

64 bit uzunluğa sahip bir int var. İkinci ve üçüncü baytlarda saklanan bir 16 bit imzalanmış int alıp 32 bitlik bir değere eklemem gerekir.C++, daha küçük türlere dökülürken kesiliyor

u32 Function(s32 value , u64 bitfield) 
{ 
    return value + (s16) (bitfield >> 8) 
} 

Ben genişlemeden önce bir 32 bitlik imzalı int için bir 16 bitlik işaretli int bit maskesini atmak derleyici güvenmek ve ek gerçekleştirir Can: Böyle bir şey kullanıyorum? Değilse, kalan baytları başka nasıl kırpmalı ve ihtiyacım olan tür dönüşümü nasıl yapmalıyım?

cevap

6

Evet, derleyici ve mimariye özgü davranışlara güvendiğiniz uyarıyla. Tabii ki, bu davranışa güvenmek sizi gerçekten zor "teşhis" (hata) haline getirecektir.

Sen özellikle istediğini (derleyici söylüyorum) dışarı yazma optimizasyon kaçırılmasının ve diğer geçiş gereksiz kod ortadan muhtemelen daha çok işinize:

u32 Function(s32 value, u64 bitfield) 
{ 
    // Extract 16 bit qty from 64-bit: (x|x|x|x|x|1|2|x), preserving 
    // signedness 
    return value + (s32) (((bitfield << 40) >> 48) & 0xffffffff); 
} 

(Evet, ayrıca olur bir yorum koyarak Gelecekte devam eden bakım yardımcıları.)

+0

Bu çözüm istenmeyen bilgileri keserken, 16 bit işaretini korumaz. Aşağıdaki gibi bir şey kullanmayı düşünürdüm: dönüş değeri + ((s32) bit alanı << 8) >> 16); Bunun işe yarayacağını düşünürken, şaşırtıcı derecede çirkin buluyorum. – Limne

+1

Tamam, imzayı korumak istediğiniz doğru nokta. Bununla birlikte, "çirkin" olmasına rağmen, niyetleriniz ne olduğu açık (bit özütleme) ve imzayı korur. Derleyici uygun talimatları seçmenin zor işini yapsın. Erken optimize etmeyin. –

+0

Mutlaka gerekli olana kadar 'bitfield 'üzerinde' u64 'olarak imzayı korumak ve işlemleri korumak için güncellendi. –

İlgili konular