2010-04-22 23 views
5

Tôi đang cố gắng tìm hiểu xem chuẩn C (C90, mặc dù tôi đang làm việc với cuốn sách C99 chú thích của Derek Jones) đảm bảo rằng tôi sẽ không mất chính xác nhân hai giá trị 8 bit chưa ký và lưu trữ thành 16 bit kết quả. Một tuyên bố ví dụ là như sau:C: 8x8 -> 16 bit nhân chính xác được đảm bảo bởi các chương trình khuyến mãi số nguyên?

unsigned char foo; 
unsigned int foo_u16 = foo * 10; 

Keil chúng tôi 8051 trình biên dịch (v7.50 hiện nay) sẽ tạo ra một hướng dẫn MUL AB mà các cửa hàng MSB vào sổ đăng ký B và LSB trong accumulator. Nếu tôi đúc foo đến một int unsigned đầu tiên:

unsigned int foo_u16 = (unsigned int)foo * 10; 

sau đó trình biên dịch sẽ quyết định một cách chính xác tôi muốn một int unsigned đó và tạo ra một cuộc gọi tốn kém để một số nguyên thói quen nhân 16x16 bit. Tôi muốn tranh luận ngoài sự nghi ngờ hợp lý rằng biện pháp phòng thủ này là không cần thiết. Khi tôi đọc các chương trình khuyến mãi số nguyên được mô tả trong 6.3.1.1, hiệu ứng của dòng đầu tiên sẽ như thể foo và 10 được đẩy vào int không dấu, phép nhân được thực hiện và kết quả được lưu trữ dưới dạng int không dấu trong foo_u16. Nếu trình biên dịch biết một lệnh mà thực hiện phép nhân 8x8-> 16 bit mà không làm mất độ chính xác, thì càng nhiều càng tốt; nhưng độ chính xác được đảm bảo. Tôi có đọc chính xác không?

Trân trọng, Craig BLOME

Trả lời

5

Chương trình khuyến mãi được đảm bảo, nhưng chương trình khuyến mãi được thực hiện để signed int loại nếu phạm vi của unsigned char phù hợp với phạm vi signed int. Vì vậy (giả sử nó phù hợp) từ quan điểm ngôn ngữ của xem

unsigned int foo_u16 = foo * 10; 

của bạn là tương đương với

unsigned int foo_u16 = (signed) foo * 10; 

trong khi những gì bạn dường như muốn

unsigned int foo_u16 = (unsigned) foo * 10; 

là Kết quả của phép nhân có thể khác nhau nếu nó (kết quả) không phù hợp với phạm vi signed int.

Nếu trình biên dịch của bạn diễn giải một cách khác, nó có thể là một lỗi trong trình biên dịch (một lần nữa, với giả định rằng phạm vi unsigned char phù hợp với phạm vi signed int).

+1

Miễn là 'UCHAR_MAX' nhỏ hơn 3277 (và câu hỏi của OP ngụ ý rằng' char' là 8 bit, vì vậy điều này là đúng), thì kết quả chắc chắn sẽ khớp với 'ký int' và do đó kết quả phải là giống nhau. – caf

+0

Ngoài ra, một cách khác để thực hiện phép nhân trên các toán hạng 'unsigned int' sẽ chỉ định hằng số là' 10U'. – caf

+0

@caf: Vâng, bạn nói đúng. Mặc dù sự khác biệt về khái niệm là ở đó, kết quả sẽ không tràn. – AnT

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