2016-04-14 18 views
6

Tôi có một int dài 64 bit với một số bitfield được đóng gói trong đó. Tôi cần một mất 16-bit ký int được lưu trữ trong byte thứ hai và thứ ba và thêm nó vào một giá trị 32-bit. Tôi đang sử dụng một cái gì đó như thế này:C++ cắt ngắn khi truyền sang các loại nhỏ hơn

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

Tôi có thể dựa vào trình biên dịch để nhập bitfield vào một ký 16 bit trước khi nó mở rộng nó thành một ký 32 bit và thực hiện bổ sung không? Nếu không, làm cách nào khác tôi nên cắt bớt các byte còn lại và thực hiện chuyển đổi loại mà tôi yêu cầu?

Trả lời

6

Có, với thông báo trước rằng bạn đang dựa vào hành vi cụ thể về trình biên dịch và kiến ​​trúc. Tất nhiên, dựa vào hành vi này sẽ dẫn bạn vào thực sự khó chẩn đoán "tính năng" (lỗi).

Bạn đang có lẽ tốt hơn viết ra (kể trình biên dịch) những gì bạn muốn đặc biệt, cho phép đèo tối ưu hóa và đèo khác loại bỏ mã không cần thiết:

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); 
} 

(Vâng, đặt một bình luận cũng sẽ giúp các nhà duy trì trong tương lai.)

+0

Trong khi giải pháp này cắt bớt thông tin không mong muốn, nó không giữ lại dấu hiệu của 16 bit. Tôi muốn xem xét sử dụng một cái gì đó như: giá trị trả lại + ((s32) bitfield << 8) >> 16); Trong khi tôi tin rằng điều này sẽ làm việc, tôi thấy nó đáng kinh ngạc xấu xí. – Limne

+1

Ok, điểm công bằng mà bạn muốn duy trì sự ký kết. Tuy nhiên, mặc dù "xấu xí", rõ ràng ý định của bạn là gì (trích xuất bit) và bảo tồn tính hợp lệ. Hãy để trình biên dịch thực hiện công việc khó khăn trong việc chọn hướng dẫn thích hợp. Không tối ưu hóa sớm. –

+0

Được cập nhật để duy trì tính hợp lệ và duy trì hoạt động trên 'bitfield' dưới dạng' u64' cho đến khi cần thiết. –

Các vấn đề liên quan