есть ли объединенная инструкция, которая может выполнять * 10 ^ n в одной инструкции? - PullRequest
1 голос
/ 19 июня 2020

Вызов a * pow(10.0, n) на любом производном языке C приводит к двум ошибкам округления, но мне требуется только одна ошибка округления, которая может быть предоставлена ​​одной объединенной инструкцией.

Например, a=39762108874335653 n=-297 должен дать 3.9762108874335653E-281 (что может быть проверено путем анализа строки "3.9762108874335653E-281" или использования арифметики произвольной точности c и вывода числа с плавающей запятой), но указанный в кавычках код возвращает 3.976210887433566E-281.

Это приводит вернемся к вопросу: существует ли объединенная инструкция (или функция C), которая может выполнить этот расчет с максимально возможной точностью для машины?

Меня интересует только случай, когда a и n - целые числа, результат - число двойной точности с плавающей запятой. Обратите внимание, что a может не быть точно представленным как число с плавающей запятой.

Преобразование в строку и синтаксический анализ не являются приемлемым решением (это слишком медленно), и при этом не используются библиотеки произвольной точности (например, Java s BigDecimal, также потому, что он слишком медленный).

Обратите внимание, что существует аналогичная функция C stdlib, ldexp (связанная с scalbn), которая использует base2 и поэтому вычисляет a * 2^n как единая объединенная инструкция.

Мне известны инструкции, перечисленные в https://en.wikipedia.org/wiki/C_mathematical_functions

Не повторяется Математика с плавающей запятой не работает ? это не попытка понять, как работает округление. Он просто спрашивает: существует ли эта функция где-нибудь, в идеале в слитой инструкции ЦП для максимальной производительности? Очевидно, что обходной путь в отсутствие такой вещи - использовать произвольную точность, но это довольно тяжело.

1 Ответ

0 голосов
/ 10 июля 2020

Ответ - «нет», нет ни одной инструкции, которая могла бы выполнить эту операцию, на что ответил @ eri c -postpischil в чате , и доказательства этого могут быть подтверждены тот факт, что стандартные библиотеки использовали бы его, если бы он был доступен, например glib c strtod

Однако, хотя нет единой инструкции CPU, можно извлечь реализацию strtod для работы для целочисленного ввода, как это было запрошено в этом вопросе, как это было сделано Alex Huszagh в Rust. Алгоритмы, обсуждаемые здесь, эффективно используют a * pow(10.0, n), когда мантисса оценивается как достаточно мала (предпочитая деление для отрицательного n), и возвращаются к алгоритмам сходимости для устранения ошибок округления.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...