Как напечатать значение с плавающей запятой из st (0) в сборке 8086 dosbox [duplicate]

1
задан phuclv 30 May 2014 в 14:47
поделиться

3 ответа

Форматирование числа с плавающей запятой довольно нетривиально. Поиск, например. для алгоритма Dragon4 ( здесь есть один результат ).

Очень, very наивно, вы можете попробовать это:

  1. Ручка NaN и бесконечность.
  2. Распечатайте знак (отметьте < 0). Предположим, что в дальнейшем число является положительным вещественным.
  3. Если >= 1, усечь и использовать знакомое целочисленное форматирование для печати целой части. (Для этого должна быть машинная инструкция для любого оборудования, имеющего блок с плавающей точкой.)
  4. Печать десятичного разделителя; теперь продолжайте умножать на 10 и печатайте усеченную интегральную цифру.
  5. Остановитесь, когда достигнете желаемой точности; подумайте о правильном округлении последней цифры.
5
ответ дан Kerrek SB 18 August 2018 в 04:07
поделиться
  • 1
    Большое спасибо. Кстати, что с этим «очень»? Если это будет «очень» медленно? – user35443 13 July 2013 в 18:23
  • 2
    @ user35443: Поскольку я взбесил это, не думая об эффективности, я предполагаю, что это будет ужасно медленным. Я думаю, что момент Dragon4 должен был быть быстрым по сравнению с литературой в то время. Я не знаю никаких подробностей, но представьте, что моя идея делится на 10 много , и это довольно медленное вычисление. – Kerrek SB 13 July 2013 в 18:32

Если допустимо печатать как 1.d1d2d3d4d5 ... * 2 ^ e1e2e3, то преобразование числа с плавающей запятой в десятичное (-ish) представление может быть простым. Реализация может быть найдена здесь .

Если вам нужно научное представление 1.d1d2 ... * 10 ^ e1e2e3, тогда наивный подход к многократному делению на 10 и извлечению цифр из номер, который у вас есть в формате с плавающей запятой. Вам понадобится какая-то многоцелевая целочисленная библиотека. (Повторно умножить на 10, чтобы извлечь цифры после точки.)

3
ответ дан Pascal Cuoq 18 August 2018 в 04:07
поделиться
  • 1
    Я не знаком с этим языком, но все равно спасибо за вашу помощь. Думаю, я выберу наивный путь. – user35443 13 July 2013 в 18:22

Решение Kerrek SB верное. Но вы можете сделать это быстрее без какого-либо цикла (или меньше циклов). Просто умножьте часть дроби на 10precision. Уменьшение числа или умножений также уменьшает кумулятивную ошибку, если вы выполняете математику с типом с плавающей точкой. Для точного преобразования вам нужно использовать тип с плавающей запятой с более высокой точностью.

Например, вы хотите преобразовать 0.1234567 с 5 цифрами точности, умножить число на 10000 и получить int-часть. Если требуется округление, умножьте его на 100000 и округлите последнее число

1
ответ дан phuclv 18 August 2018 в 04:07
поделиться
  • 1
    Такой подход является быстрым и легким в тех случаях, когда речь идет не о точном округлении, а о точности вблизи пределов этого типа. Я бы предположил, что последний шаг часто может быть упрощен путем умножения на 200000, преобразования в целое число, добавления одного и деления на два. Обратите внимание, что очень важно знать, что в разных сценариях числа могут различаться по-разному. У Turbo C 2.00 была ошибка, где printf("%1.2f",99.999999996); определял бы, что две цифры слева от десятичной точки, преобразуют значение в строку («100,00»), а затем ... – supercat 26 July 2013 в 17:07
  • 2
    ... напечатать результат, начинающийся с двух цифр слева от десятичной точки (т. е. «00.00»). К сожалению. Тем не менее, ваш подход гарантирует, что даже если он не всегда даст точные значения, они вряд ли будут просто равными. – supercat 26 July 2013 в 17:11
  • 3
    Наконец, я нашел другое решение, редактируя сообщение. – user35443 26 July 2013 в 17:55
  • 4
    Вам все еще нужен цикл для преобразования int( frac(x)*10000 ) в строку, по одной десятичной цифре за раз! Но он будет использовать целочисленное деление вместо умножения FP ( Как напечатать целое число в Программе уровня сборки без printf в библиотеке c? ). (Если вы не можете использовать printf для целочисленных форматов, но не плавать, но он должен зацикливаться внутри.) – Peter Cordes 30 June 2018 в 04:02
  • 5
    Я предполагаю, что таблица поиска 100 или 1000 правдоподобна, возможно, с 16-битным индексом в упакованный буфер строк C. Или где строки - это строки C, заполненные фиксированной длиной. Но 10-5 или более больших LUT, вероятно, не подходят для большинства случаев использования. – Peter Cordes 30 June 2018 в 04:21
Другие вопросы по тегам:

Похожие вопросы: