... всего 6 цифр после десятичной дроби, но только 2 цифры от исходного ответа и оставшиеся цифры равны 0.
Выведите округленный ответ с желаемой точностью, а затем напечатайтенули с "%0*d", zeros, 0
.
Или постобработка текста для получения округленного вывода.
#include <math.h>
#include <stdio.h>
#ifndef M_PI
#define M_PI 3.1415926535897932384626433832795
#endif
int main() {
double r = 2.0;
double a = M_PI * pow(r, 2);
int total_digits_after_decimal = 6;
int zeros = 4;
printf("%.*f%0*d\n", total_digits_after_decimal - zeros, a, zeros, 0);
char buf[4096];
int len = sprintf(buf, "%.*f", total_digits_after_decimal, a);
buf[len - zeros] = '\0';
printf("%s%0*d\n", buf, zeros, 0);
return 0;
}
Вывод
12.570000
12.560000
Примечание: подходprintf("%.*f",6,trunc(a*100)/100);
работает для многих значений a
, но завершается ошибкой, когда a
очень велико, и для выбранных значений, когда a*100
неточно и находится рядом со значением целого числа.
Обычно возникают проблемывозникают случаи обработки бесконечного числа, а не числа.
В наихудшем случае размера буфера можно использовать DBL_MAX_10_EXP
(часто 308) до нужного размера buf[]
.
#include <float.h>
// sign digits . precision \0
char buf[1 + DBL_MAX_10_EXP + 1 + total_digits_after_decimal + 1];
Глубже:
Подход с постобработкой все еще округляет ответ, но на 6-м десятичном знаке, а не на 2-м.
Чтобы не допускать округления, точность должна увеличиваться как минимум DBL_DECIMAL_DIG
(C11) мест или total_digits_after_decimal + 1
- что больше.Это гарантирует, что вывод текста округляется за пределы того, что может повлиять на вещи.
int len = sprintf(buf, "%.*f", DBL_DECIMAL_DIG, a);
buf[len - DBL_DECIMAL_DIG - (total_digits_after_decimal - zeros)] = '\0';
printf("%s%0*d\n", buf, zeros, 0);
Обратите внимание на @ Пол Огилви хороший совет.Цели кодирования здесь сомнительны для производственного кода.
Такие пользователи, как @ kvantour , подтверждают сомнительную потребность в этой любопытной цели.