Магическое число 2⁵² вам очень поможет

Языки - это не то, о чем мы здесь заботимся, но для простоты предположим, что мы используем C в следующем контексте.

Вопрос, на который будет отвечать эта статья:

Как округлить (обрезать) двойник без приведения типов?

Вопрос может звучать как-то глупо. Кому нужно заботиться о способе усечения или округления двойника без приведения типов? Приведение типов так легко решить проблему, и для этой цели служат некоторые инструкции по сборке (например, `fcvtzs` в ARM).

Конечно, это серьезный вызов, но в настоящий момент эта проблема существует. Если вы посмотрите на список встроенных функций SSE SIMD, то обнаружите, что

Нет встроенного элемента, который отвечает за преобразование double в int64

Это вызовет огромные проблемы для инженера, который работает над оптимизацией программы с помощью технологии SIMD. Таким образом, это решение может стать вашей линией жизни.

Решение довольно простое. Давайте взглянем на вики-страницу Формат двойной точности с плавающей запятой.

Между 2⁵² = 4 503 599 627 370 496 и 2 ³ = 9 007 199 254 740 992 представимые числа - это в точности целые числа.

Почему?

Причина довольно проста. Давайте посмотрим на схему с плавающей запятой двойной точности в IEEE754.

Число с плавающей запятой двойной точности состоит из 3 частей.

  1. знаковый бит (1 бит)
  2. экспоненциальная часть (11 бит)
  3. дробная часть (52 бита)

Как видите, в дробной части всего 52 бита. Следовательно, любое целое число меньше 2⁵² может быть полностью представлено фракционной частью.

Для целых чисел больше 2⁵² последними несколькими битами можно пренебречь, поскольку дробь просто не может выразить такой объем информации.

Как только мы получим знания о 3 частях числа с плавающей запятой двойной точности в IEEE754, тогда будет довольно легко понять принцип метода усечения.

Возьмите следующий расчет, тогда вы можете просто обрезать плавающее число двойной точности. Здесь T - номер таргетинга.

(T + 2⁵²)-2⁵²

Как это работает? Первый шаг сопоставляет целевое плавающее число двойной точности с диапазоном, в котором может быть точно представлена ​​его целая часть. Другими словами, будет удалена дробная часть.

Ниже приведена демонстрация усечения с помощью встроенных функций Intel SSE.

Ссылка