Вопрос

Как создать строку, чтобы она форматировала числа с плавающей запятой, чтобы они не имели конечной десятичной точки или цифр, если она была целым числом, но НЕ переключались на научную запись для больших чисел?

Когда я это сделаю:

float myFloat= 15.6f;
float myInt = 5.0f;
float myLarge = 7000000.0f;
sprintf(out, "my float is %g", myFloat);
sprintf(out, "my int is %g", myInt);
sprintf(out, "my large is %g", myLarge);

Я получаю что-то вроде:

my float is 15.6
my int is 5
my large is 7e+07f

Мне нужна вся строка формата, которая даст 15,6, 5 и 700000.

Отредактированные комментарии причин не выполняют форматирование:

Я так и думал. но обертка довольно неудобна, так как строки формата встроены в более длинные строки формата:

sprintf(buf, "%d %g", myInt, myFloat);

как вы это заверните?

sprintf(buf, "%d %g", myInt, Wrapper(myFloat));??

что должен вернуть Wrapper? Или хуже:

sprintf(buf, "%d %s", myInt, Wrapper(myFloat));?? 
Это было полезно?

Решение

Я не думаю, что вы можете получить это с помощью % g , так как % g дает вам меньше % e или % F .

Итак, я не думаю, что есть единственный аргумент printf , который вас устраивает. Для 15.6 вы можете использовать % 2.1f ; для 7000000 вы можете использовать % 7.0f .

Лучше всего вам написать функцию-обертку, которая бы смотрела на размер вашего значения и применяла правильный аргумент printf .

Другие советы

Вы можете отформатировать с помощью "%. * f", что позволяет передать точность в качестве отдельного параметра, например, в. Sprintf. Я использовал это в прошлом, когда я хотел отображать 0, 1, 2 или, может быть, 3 цифры без дополнительных конечных 0. Напишите небольшую вспомогательную функцию, которая принимает double / float и возвращает целочисленную точность (умножив на 1000, а затем выполнив по модулю 10, 100, 1000). Затем вызовите sprintf с «%. * F», вызовите вспомогательную функцию и передайте число с плавающей точкой.

Подход Майка разумен, но вы можете вычислить количество цифр напрямую, используя функцию log10, и использовать floor или ceil, чтобы убедиться, что у вас действительно целочисленное значение. Что-то вроде:

#include <math.h>
double x;
...
if (floor(x) == x && x != 0.0) { // x is an non-zero integer value
    int digits = floor(log10(fabs(x)+0.5)) + 1;
    printf("x is %.*f\n", digits, x);
}

Распаковывая эту цепочку вызовов функций, мы сначала берем абсолютное значение, чтобы убедиться, что аргумент неотрицательный, добавляем 0,5 к известному целочисленному значению, чтобы учесть любые возможные ошибки округления при вычислении log10 с точной степенью 10 , объедините log10 и floor, чтобы получить показатель степени наибольшей степени 10 меньше, чем fabs (x) +0.5, и, наконец, добавить 1, чтобы получить количество цифр, необходимое для представления x. Вот некоторые примеры значений (из OpenOffice, но функция C log10 должна вычислять с одинаковой точностью):

         x          log10(x+0.5)
         1  0.176091259055681000
         9  0.977723605288848000
        10  1.021189299069940000
        99  1.997823080745730000
       100  2.002166061756510000
       999  2.999782798454140000
      1000  3.000217092972230000
     10000  4.000021714181250000
    100000  5.000002171466980000
   1000000  6.000000217147190000
  10000000  7.000000021714720000
 100000000  8.000000002171470000
1000000000  9.000000000217150000

Замените% g на% .10g, чтобы отобразить до 10 значимых цифр.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top