Выведите значение с плавающей запятой с постоянным количеством символов в C ++ - PullRequest
3 голосов
/ 29 февраля 2012

У меня проблемы с выполнением того, что я считаю довольно простой задачей на C ++.Я пытаюсь вывести значение с плавающей запятой для записи в файл журнала.Файл журнала содержит 7 символов, предназначенных для вывода числа, но я считаю, что будет немного нетривиально получить постоянный вывод из 7 символов в широком диапазоне значений различных величин, знаков и точностью (например, 1, -0,60937, 0,60937, 0,009371, -0,009371).У меня есть какой-то взломанный способ сделать это:

int desiredPrecision = 6;
if (runningAvg < 0)
  desiredPrecision--;
if (std::abs((long) runningAvg) < 1)
  desiredPrecision--;
else
  theFile << std::showpoint;

theFile.precision (desiredPrecision);

theFile.fill('0');
theFile.setf(std::ios_base::left, std::ios_base::adjustfield);
theFile.width(7);
theFile << runningAvg << std::endl;

Но этот способ кажется мне чрезвычайно хакерским.Он работает с числами, такими как: -0,6037 (выходные данные: -0,6094)

-1,7 (-1,7000)

-1 (-1,0000)

0,6937 (0,60937)

0,00937 (0,00937)

, но он разрывается с 0,009371 (0,009371)

и

-0,009371 (-0,009371)

Теперь яМожно добавить еще один уровень операторов if-else для работы с числами с малой величиной, но это, кажется, только добавляет к уровню хакерства, а не является чистым способом сделать это.Я немного поиграл с fprintf, но, похоже, его больше интересует строгое математическое определение точности, тогда как в этом приложении я больше беспокоюсь об ограничении ширины поля до 7 символов.(Я также могу рассчитывать на то, что эти числа никогда не будут такими большими, что я переполню 6 символов плюс знак)

Я что-то упускаю здесь очевидное?У кого-нибудь есть советы по менее взломанному способу достижения этого?

Ответы [ 3 ]

1 голос
/ 29 февраля 2012

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

1 голос
/ 29 февраля 2012

Если вас не интересует точность (или достаточно, чтобы использовать одинаковую точность для всех чисел), вы можете использовать один и тот же формат "%7.0e" для всех чисел.

Пример

#include <stdio.h>

static const char* format = "%7.0e";

int main() {
  double a[] = {1, -0.60937, 0.60937, 0.009371, -0.009371,
               -1, -1.2e8, 1e-4, 1e-5, -1.5e-321, 0/.0, 1/0.};
  for (unsigned i = 0; i < sizeof(a) / sizeof(*a); ++i) {
    printf(format, a[i]);
    puts("");
    if (snprintf(0,0, format, a[i]) != 7)
      return 1;
  }
}

Выход

  1e+00
 -6e-01
  6e-01
  9e-03
 -9e-03
 -1e+00
 -1e+08
  1e-04
  1e-05
-2e-321
    nan
    inf
1 голос
/ 29 февраля 2012

Не знаю, как это сделать с вещами iostream, но я думаю, что строка формата ?printf, которую вы ищете, является одной из следующих:

  • %.4f для отрицательныхчисла и %07.5f для положительных чисел.
  • %+.4f (положительные числа будут иметь начальный +)
  • % .4f (положительные числа будут иметь начальный пробел)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...