2010-09-28 22 views
11

Tôi có một vấn đề khá phổ biến trong mã mà tôi đang viết tại thời điểm mà tôi muốn có một số nguyên chỉ có thể tồn tại trong một phạm vi nhất định trong đó phạm vi là [bắt đầu, kết thúc). Về cơ bản, tôi muốn có thể thực hiện một số việc như sau:Có lớp Cyclic Integer chuẩn trong C++ không?

cyclic_int ci(4, 8); 

ci = 4; 
assert(ci == 4); 
ci += 3; 
assert(ci == 7); 
ci += 2; 
assert(ci == 5); 
assert(ci == 13); 

Và tất cả điều đó sẽ trở lại đúng. Về cơ bản các lớp tự động áp dụng modulus (%) cho tôi và số nguyên hoạt động như một số nguyên cyclic trong phạm vi mà tôi bắt đầu với nó. Tôi có thể thực hiện lớp này bản thân mình và quá tải tất cả các nhà khai thác phổ biến để làm cho nó hoạt động độc đáo với các số nguyên bình thường nhưng nó có vẻ giống như một lớp hữu ích mà ai đó có thể đã làm trước đây. Vì vậy, câu hỏi của tôi là, có một lớp học phổ biến như thế này ra có một nơi nào đó mà tất cả mọi người sử dụng hoặc tôi đang nghĩ đến việc làm nó một cách sai lầm và là có một cách đơn giản tốt hơn.. (Mục đích của tôi là không phải liên tục suy nghĩ về việc áp dụng toán tử% hoặc bất kỳ hàm tương tự nào trên nó).

Edit: Tôi quyết định viết một riêng tôi cũng chỉ để cho vui: http://github.com/robertmassaioli/wrapping_number

+1

As far như tôi biết không có "tiêu chuẩn công nghiệp" cho loại điều này - như thư viện Boost, nếu đó là ý của bạn. Nhưng như bạn đã nói, cần phải dễ dàng thực hiện một lớp như vậy và quá tải tất cả các toán tử cần thiết. –

+1

Sử dụng nhận xét thay vì trả lời vì 1) Tôi chưa bao giờ sử dụng nó và 2) Nó chưa phải là thư viện Boost chính thức nhưng: Boost.ConstrainedValue có một "wrap_int" trông rất giống với những gì bạn đang tìm kiếm: http: //student.agh.edu.pl/~kawulak/constrained_value/constrained_value/tutorial.html#constrained_value.tutorial.other_error_policies_for_bounded_objects –

+0

@Eric: Đó chính xác là những gì tôi đang tìm kiếm nhưng nó chưa nằm ngoài các thư viện tăng cường. Tôi đã thử nhìn xung quanh và không thể tìm thấy một thực hiện tham chiếu. Tôi sẽ tiếp tục tìm kiếm nhưng bạn có biết nó ở đâu không? –

Trả lời

2

Tôi chưa bao giờ sử dụng và nó chưa phải là thư viện Boost chính thức, nhưng Boost.ConstrainedValue có wrapping_int trông rất giống với những gì bạn đang tìm kiếm.

Mặc dù nó chưa được một phần của Boost, nó đã được xem xét và IIUC, có điều kiện chấp nhận thời gian gần đây: http://lists.boost.org/boost-announce/2010/09/0265.php

Thư viện hiện có sẵn tại http://rk.dl.pl/f/constrained_value.zip

Các tài liệu là ở http://rk.dl.pl/r/constrained_value

+0

Tôi cũng đã viết một cuốn sách của riêng tôi cũng chỉ để cho vui: http://github.com/robertmassaioli/wrapping_number –

4

Không phải là nó dễ dàng hơn để sử dụng chức năng normalize?

int normalize(int val, int start, int end) 
{ 
    return (val - start) % (end - start) + start; 
} 


int ci = 4; 
assert(ci == 4); 
ci = normalize(ci + 3, 4, 8); 
assert(ci == 7); 
ci = normalize(ci + 2, 4, 8); 
assert(ci == 5); 
assert(ci == 13); 
+1

Đó là chính xác những gì tôi đã cố gắng tránh vì tôi không muốn phải thực sự suy nghĩ về việc áp dụng các chức năng bình thường hóa (vì tôi sẽ quên cuối cùng). Và lời khẳng định cuối cùng cũng sẽ thất bại? –

+0

Trên thực tế, tôi nghĩ rằng khẳng định cuối cùng sẽ thất bại, bởi vì 13 không được định nghĩa là một số giới hạn phạm vi, tôi sẽ sử dụng khẳng định (ci == cyclic_int <4,8> (13)); (mẫu là thuận tiện ở đây) – stefaanv

+0

@stefaanv: Tôi nghĩ rằng những gì anh ấy nhận được là 13 nên được đồng dư đến 5 trong cyclic_int (4, 8) (tức là bao gồm các số nguyên 4, 5, ...12), đó là. Tôi đồng ý với khái niệm về một mẫu ... cung cấp cách gõ mạnh hơn. – andand

1

Đây có thể không chính xác những gì bạn muốn, nhưng bạn có thể quan tâm đến một trong nhiều thư viện trường Galois ngoài đó (http://www.google.co.uk/search?q=galois+field+c%2B%2B+library). Tôi đã không bao giờ sử dụng bất kỳ của họ, vì vậy tôi không thể đưa ra một khuyến nghị cụ thể.

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