C printf спецификатор функции - PullRequest
2 голосов
/ 23 февраля 2012

Мне нужно распечатать значение с плавающей запятой с 16 значащими цифрами.

Прямо сейчас, когда я печатаю, оно печатает

, то есть 2,555556

, когда я хочу этораспечатать: 2.555555555555556 /// Всего 16 цифр

Мой спецификатор printf в настоящее время: "% 20.18lf"

ideas?

Ответы [ 3 ]

3 голосов
/ 23 февраля 2012

Если значение имеет тип float, вы, вероятно, не получите более 7 значащих цифр после десятичной точки. Если это тип double, вы можете получить около 15. В зависимости от системы, long double может быть не более точным, чем double; на моем я получаю около 17 значащих цифр после десятичной точки.

В большинстве кодов с плавающей запятой используется тип double; float гораздо менее точен и часто не значительно быстрее.

Я немного удивлен, что вы получили 2.555556, а не что-то вроде 2.555555582046508789 с форматом "%20.18lf".

Кстати, l (строчная L) не обязателен. Для double используется формат "%f", а для float аргументы printf повышаются до double, поэтому "%f" является правильным для float и double. Формат long double - "%Lf".

Вот тестовая программа, которую я написал:

#include <stdio.h>
int main(void) {
    const float f        = 23.0/9.0;
    const double d       = 23.0/9.0;
    const long double ld = 23.0L/9.0L;
    printf("%20.18f\n%20.18f\n%20.18Lf\n", f, d, ld);
    return 0;
}

и вывод, который я получил в моей системе:

2.555555582046508789
2.555555555555555358
2.555555555555555556
0 голосов
/ 23 февраля 2012

C float или double недостаточно точны, в основном вам нужна высокоточная функция деления.Вот что я написал.Это для целочисленного деления.Возможно, вам придется пересмотреть его для деления поплавка.

int dividend=121, divisor=9;
int quotient,remainder;

//first print out the number before decimal point
quotient=dividend/divisor;
printf("%d", quotient);
remainder=dividend-quotient*divisor;

//print out decimal point
printf(".");

int digit_num=20;//this can be any precision you want

//second we calculate the number after decimal point
for(int i=0;i<digit_num;i++)
{
    remainder=remainder*10;
    quotient=remainder/divisor;
    remainder=remainder-quotient*divisor;
    printf("%d", quotient );
    dividend=remainder;
}

printf("\n");

printf("%d digits after decimal point has been printed out\n", digit_num );
0 голосов
/ 23 февраля 2012

Следующий код работает хорошо (вы должны включить C99, так как спецификатор %lf не является частью более ранних стандартов):

#include <stdio.h>

int main(void)
{
        volatile float v = 2.555555555555556;
        printf("%20.18lf\n", v);
        return 0;
}

Печатает следующее:

$ gcc -std=c99 -Wall -pedantic -o test ./test.c 
$ ./test 
2.555555582046508789
$ 

Если значение короче, скажем, 2,5, оно добавляет к нулю правое число - 2.500000000000000000.

Итак, у вас есть ошибка в другом месте. Как правило, вы должны опубликовать минимальный пример самосогласованного кода, который воспроизводит проблему. В противном случае вы по своему усмотрению.

...