Как правильно обрабатывать округление строк с плавающей запятой в IEEE 754? [закрыто]C++

Программы на C++. Форум разработчиков
Ответить
Anonymous
 Как правильно обрабатывать округление строк с плавающей запятой в IEEE 754? [закрыто]

Сообщение Anonymous »

Мне пришлось реализовать свои собственные алгоритмы преобразования строк в числа с плавающей запятой и чисел с плавающей запятой для grisu и Unicode, используя шаблоны C++. Я использовал следующий алгоритм, найденный в статье Википедии «Формат с плавающей запятой одинарной точности»:
  • рассмотрим действительное число с целой и дробной частью. например 12,375
  • преобразовать и нормализовать целую часть в двоичную
  • преобразовать дробную часть, используя следующую технику, как показано здесь
  • добавить два результата и настроить их для правильного окончательного преобразования
Я не уверен, что делать, когда строка преобразование в число с плавающей запятой имеет большую точность цифр, чем я могу сохранить в 32-битном (например) формате с плавающей запятой, но оно не достигает +/- бесконечности, и правильный способ округления, следует ли делать это в базе 2 или базе 10. В статье вики говорится, что алгоритм включает округление, но не затрагивает переполнение. Для 32-битных чисел с плавающей запятой точность составляет только 7 цифр. Для 64-битных чисел с плавающей запятой точность составляет 16 цифр. Любые дополнительные числа необходимо округлять с использованием правил округления IEEE 754.

Пример

Вариант по основанию 2< /h2>

Сначала мы конвертируем целую часть, как и алгоритм в статье вики, путем сканирования до младшей значащей цифры, а затем анализируем обратно до самой старшей цифры, умножая каждую цифру на степень 10 (т. е. стандартный алгоритм преобразования строки в целое число) и использование цикла умножения без знака для обнаружения переполнения битов, округление по основанию 2; мне это кажется неправильным, и я думаю, что статья в Википедии - не лучший алгоритм.

Вариант по основанию 10

Мы преобразуем каждое число в экспоненциальное представление с одной старшей цифрой, например, преобразуя 123456780123456789.012. до 1,234567e20 с использованием правил округления IEEE 754. Звучит как лучший выбор, потому что нам нужно проанализировать текст только один раз, и нам нужно сканировать показатель степени, и мы можем избежать алгоритма преобразования строки в целое число. Округление по основанию 10 звучит наиболее разумно, поскольку число по-прежнему находится в десятичной системе, и вам нужно прочитать цифры и десятичные дроби только один раз, не умножая на степень 10. Если это предпочтительный метод, то запись в вики должна быть обновлена. Я уверен, что этот алгоритм работает быстрее для чисел с положительным показателем степени, но может иметь ошибку с числами с отрицательным показателем из-за деления, но я не знаю.

Подробнее здесь: https://stackoverflow.com/questions/513 ... t-rounding
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C++»