Я посмотрел на бумагу djb, и вам стало проще, поскольку 31 бит удобно вписывается в 53-битную точность с двойным значением. Предполагая, что ваша контрольная сумма состоит из некоторых кольцевых операций над Z / (2 ** 31 - 1), будет проще (и быстрее) решить упрощенную задачу вычисления небольшого представителя x mod Z / (2 ** 31 - 1); в конце вы можете использовать целочисленную арифметику, чтобы найти каноническую, которая медленная, но не должна происходить слишком часто.
Основной шаг сокращения состоит в замене целого числа x = y + 2 ** 31 * z на y + z. Уловка, которую использует djb, состоит в том, чтобы вычислить w = (x + L) - L, где L - большое целое число, тщательно выбранное, чтобы вызвать округление таким образом, чтобы z = 2 ** - 31 * w. Затем вычислите y = x - w и выведите y + z, который будет иметь величину не более 2 ** 32. (Я извиняюсь, если этой операции недостаточно, если да, пожалуйста, опубликуйте свой алгоритм контрольной суммы.)
Выбор L включает знание того, насколько точным является значение. Для модуля 2 ** 31 - 1 мы хотим, чтобы единица наименьшей точности (ulp) была 2 ** 31. Для пар в диапазоне [1.0, 2.0) ulp составляет 2 ** - 52, поэтому L должно быть 2 ** 52 * 2 ** 31. Если бы вы делали это с модулем 2 ** 7 - 1, то вы бы взяли L = 2 ** 52 * 2 ** 7. Как отмечает djb, этот трюк в решающей степени зависит от промежуточных результатов , а не , которые вычисляются с более высокой точностью.