Прежде всего, это не вопрос новичков с плавающей запятой. Я знаю, что результаты арифметики с плавающей запятой (не говоря уже о трансцендентных функциях) обычно не могут быть представлены точно и что большинство завершающих десятичных знаков не могут быть представлены точно как двоичные числа с плавающей запятой.
Таким образом, каждое возможное значение с плавающей запятой точно соответствует диадическому рациональному (рациональное число p/q
, где q
- степень 2), которое, в свою очередь, имеет точное десятичное представление.
Мой вопрос: как вы находите это точное десятичное представление эффективно? sprintf
и аналогичные функции обычно указываются только с несколькими значащими цифрами, чтобы однозначно определять исходное значение с плавающей запятой; они не обязательно печатают точное десятичное представление. Я знаю один алгоритм, который я использовал, но он очень медленный, O(e^2)
, где e
- показатель экспоненты. Здесь схема:
- Преобразование мантиссы в десятичное целое. Вы можете сделать это, вытащив биты, чтобы прочитать мантисса напрямую, или вы можете написать беспорядочный цикл с плавающей запятой, который сначала умножает значение на две силы, чтобы поместить его в диапазон 1 <= x < 10, затем вытягивает за вычетом цифры за раз, отбрасывая на int, вычитая и умножая на 10.
- Применить экспонента путем многократного умножения или деления на 2. Это операция с строкой десятичных цифр, которые вы сгенерировали. Каждые ~ 3 умножения добавят дополнительную цифру влево. Каждое отдельное разделение добавит дополнительную цифру вправо.
Действительно ли это возможно? Я сомневаюсь в этом, но я не эксперт с плавающей запятой, и я не могу найти способ выполнить вычисления base-10 в представлении чисел с плавающей запятой, не запуская возможности неточных результатов (умножения или деления на ничего, кроме мощности 2, является операцией с потерями по номерам с плавающей запятой, если вы не знаете, что у вас есть свободные биты для работы).