Tôi đang triển khai một thuật toán trong C cần thực hiện phép cộng và trừ mô-đun một cách nhanh chóng trên các số nguyên không dấu và có thể xử lý đúng các điều kiện tràn. Dưới đây là những gì tôi hiện có (hoạt động không hoạt động):Bổ sung và trừ mô-đun an toàn tràn trong C?
/* a and/or b may be greater than m */
uint32_t modadd_32(uint32_t a, uint32_t b, uint32_t m) {
uint32_t tmp;
if (b <= UINT32_MAX - a)
return (a + b) % m;
if (m <= (UINT32_MAX>>1))
return ((a % m) + (b % m)) % m;
tmp = a + b;
if (tmp > (uint32_t)(m * 2)) // m*2 must be truncated before compare
tmp -= m;
tmp -= m;
return tmp % m;
}
/* a and/or b may be greater than m */
uint32_t modsub_32(uint32_t a, uint32_t b, uint32_t m) {
uint32_t tmp;
if (a >= b)
return (a - b) % m;
tmp = (m - ((b - a) % m)); /* results in m when 0 is needed */
if (tmp == m)
return 0;
return tmp;
}
Bất kỳ ai biết thuật toán tốt hơn? Các thư viện tôi đã tìm thấy rằng làm số học mô-đun tất cả dường như được cho số lượng lớn chính xác tùy ý đó là cách overkill.
Chỉnh sửa: Tôi muốn điều này chạy tốt trên máy 32 bit. Ngoài ra, các chức năng hiện tại của tôi được chuyển đổi trivially để làm việc trên các kích thước khác của số nguyên unsigned, một tài sản mà sẽ được tốt đẹp để giữ lại.
Thật không may, tôi không thể giả định rằng a và b nhỏ hơn m đối với ứng dụng cụ thể này. – ryanc
@ryanc: bạn có thể chỉ cần thêm 'a% = m; b% = m;' vào đầu mỗi hàm. Điều này vẫn mang lại các thuật toán đơn giản hơn. Chúng có nhanh hơn hoặc chậm hơn các thuật toán trong OP, phụ thuộc vào phần cứng và các giá trị tham số. –