2009-11-19 31 views
8

bất cứ ai có thể vui lòng giải thích cách thức hoạt động (asz + 7) & ~ 7; Nó làm tròn asz thành bội số cao hơn tiếp theo của 8.Bit Hack - Làm tròn cho nhiều người trong số 8

Thật dễ dàng để thấy rằng ~ 7 tạo ra 11111000 (đại diện 8 bit) và do đó tắt 3 bit cuối cùng, do đó bất kỳ số nào được tạo ra là bội số của 8

Câu hỏi của tôi là cách thêm asz lên 7 trước khi tạo mặt nạ [chỉnh sửa] tạo ra [số cuối cùng] cao hơn tiếp theo của 8? Tôi đã cố gắng viết nó ra giấy

như:

1 + 7 = 8 = 1|000 (& ~7) -> 1000 
2 + 7 = 9 = 1|001 (& ~7) -> 1000 
3 + 7 = 10 = 1|010 (& ~7) -> 1000 
4 + 7 = 11 = 1|011 (& ~7) -> 1000 
5 + 7 = 12 = 1|100 (& ~7) -> 1000 
6 + 7 = 13 = 1|101 (& ~7) -> 1000 
7 + 7 = 14 = 1|110 (& ~7) -> 1000 
8 + 7 = 15 = 1|111 (& ~7) -> 1000 

Một mô hình dường như rõ ràng xuất hiện mà đã được khai thác .Can ai vui lòng giúp tôi nó ra?

Cảm ơn tất cả vì câu trả lời. Nó giúp xác nhận những gì tôi đang nghĩ. Tôi tiếp tục viết các mô hình trên và khi tôi vượt qua 10, tôi có thể thấy rõ ràng rằng các nos được thúc đẩy để tiếp theo "khối 8" nếu tôi có thể nói như vậy.

Xin cảm ơn một lần nữa.

Trả lời

17

Vâng, nếu bạn đang cố gắng để làm tròn xuống, bạn sẽ không cần thêm. Chỉ cần thực hiện bước tạo mặt nạ sẽ xóa các bit dưới cùng và bạn sẽ được làm tròn thành bội số tiếp theo thấp hơn.

Nếu bạn muốn làm tròn lên, trước tiên bạn phải thêm đủ để "vượt qua" bội số tiếp theo của 8. Sau đó, cùng một bước tạo mặt nạ sẽ đưa bạn quay lại bội số của 8. Lý do bạn chọn 7 đó là số duy nhất được bảo đảm là "đủ lớn" để đưa bạn từ bất kỳ số nào lên quá số bội số tiếp theo của 8 mà không tăng thêm bội số nếu số ban đầu của bạn đã là bội số của 8.

Nói chung, để làm tròn đến sức mạnh của hai:

unsigned int roundTo(unsigned int value, unsigned int roundTo) 
{ 
    return (value + (roundTo - 1)) & ~(roundTo - 1); 
} 
+1

làm tròn một số nguyên n xuống bất kỳ số nguyên m nào có thể đạt được với '(n/m) * m' –

+1

' & ~ 'bit chỉ hoạt động nếu roundTo là một sức mạnh của 2. Nói chung bạn cần' return ((giá trị) + roundTo - 1)/roundTo) * roundTo; 'thay thế. –

+0

@GregRogers, bạn có bất kỳ ý tưởng làm thế nào đắt tiền một hướng dẫn phân chia là? – Johan

3

Vâng, mặt nạ sẽ tự tạo ra chính xác bội số 8. Việc thêm 7 vào asz đảm bảo rằng bạn nhận được số tiền cao hơn tiếp theo cao hơn.

15

Thực tế việc thêm 7 vào số và làm tròn xuống.

này có hiệu quả mong muốn làm tròn lên đến nhiều tiếp theo của 8. (Thêm 8 thay vì 7 sẽ đụng một giá trị từ 8 đến 16.)

+0

Ngẫu nhiên mẹo này sẽ không hoạt động nếu số bạn muốn làm tròn thành bội số không phải là bội số của số cơ sở. Phiên bản ngắn: Bạn không thể thêm 8 và tròn thành 9, nhưng bạn có thể thêm 15 và tròn thành 16. – Broam

+0

Broam, tôi hoàn toàn không hiểu bạn đang nói gì. Thêm 8 và làm tròn xuống dường như chỉ hoạt động tốt. – Joost

4

+7 không phải là để tạo ra bội số chính xác của 8, đó là để đảm bảo bạn nhận được bội số cao nhất tiếp theo là 8.

chỉnh sửa: Bị đánh mất 16 giây và một số đơn đặt hàng có chất lượng. Ồ, quay lại rình rập.

0

Uhh, bạn vừa trả lời câu hỏi của riêng mình ??? bằng cách thêm 7, bạn đang đảm bảo kết quả sẽ ở hoặc trên bội số tiếp theo của 8. cắt ngắn sau đó cung cấp cho bạn nhiều.

1

Nếu không có sự +7 nó sẽ là nhiều nhất là 8 ít hơn hoặc bằng số orig bạn

1

Thêm 7 không tạo ra một bội số của 8. Các bội số của 8 được sản xuất bởi anding với ~ 7. ~ 7 là phần bù của 7, là 0xffff fff8 (ngoại trừ việc sử dụng nhiều bit trong một int). Điều này cắt ngắn hoặc làm tròn xuống.

Thêm 7 trước khi thực hiện điều đó đảm bảo rằng không có giá trị nào thấp hơn giá trị asz được trả lại. Bạn đã tìm ra cách hoạt động.

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