Вот решение, учитывая, что u
- некоторое целое число, а x
- конечное ненулевое двоичное число IEEE-754, с которым мы выполняем арифметические операции c IEEE-754. Предполагается, что x
представляет одно конкретное число c, как указано в IEEE-754, и предыдущие ошибки округления, возникшие при получении x
, не рассматриваются. Этот ответ относится к задействованной математике, а не к семантике Rust, поскольку я не знаком с Rust.
Сначала найдите представление x
= F
• 2 E
, где F
- нечетное целое, а E
- целое. Простой способ для этого:
- Установить
F
на x
и E
на 0. - Хотя
F
не является целым числом, умножьте F
на два и вычтите единицу из E
. - Пока
F
четное, разделите F
на два и прибавьте единицу к E
.
Все вышеперечисленное операции могут выполняться в арифметических c IEEE-754 * без ошибок округления. Если Rust предлагает метод разделения мантиссы и экспоненты числа с плавающей запятой, сродни функции C frexp
, то включение его в приведенное выше может повысить эффективность.
Теперь подумайте, является ли u
кратно x
= F
• 2 E
. По определению, это тогда и только тогда, когда существует целое число k
такое, что u
= k
• F
• 2 E
. Мы увидим, что это так, если и только если u
кратно F
и кратно 2 E
, и каждое из них можно проверить.
Если 2 E
является целым числом (E
неотрицательно) и такое k
существует, то u
кратно F
и кратно 2 E
. И наоборот, если u
не кратно F
или не кратно 2 E
, то такого k
не существует (в соответствии с основной теоремой арифметики c
F
обязательно находится в границах запрошенного целочисленного формата (это не более 53 бит), и мы предполагаем, что F
можно преобразовать в этот формат. Затем можно проверить делимость u
на F
. Если 2 E
превышает максимальное значение целочисленного формата, в котором представлено u
, то u
не является кратным 2 E
. В противном случае 2 E
можно преобразовать в формат, и можно проверить делимость u
на 2 E
.
Если 2 E
не является целым числом (E
отрицательно), то, если требуемое k
существует (поэтому u
кратно F
), оно кратно 2 - E
. И наоборот, если k
не кратно 2 - E
, тогда k
• F
• 2 E
не является целым числом, поэтому он не может равно u
. Таким образом, u
кратно x
тогда и только тогда, когда u
кратно F
.