Точное представление числа Пи с одинарной/двойной/расширенной точностью с точностью до десятичных знаков?
PI и точность числа с плавающей точкой
Ответ 1
#include <stdio.h>
#define E_PI 3.1415926535897932384626433832795028841971693993751058209749445923078164062
int main(int argc, char** argv)
{
long double pild = E_PI;
double pid = pild;
float pif = pid;
printf("%s\n%1.80f\n%1.80f\n%1.80Lf\n",
"3.14159265358979323846264338327950288419716939937510582097494459230781640628620899",
pif, pid, pild);
return 0;
}
Результаты:
[quassnoi #] gcc --version
gcc (GCC) 4.3.2 20081105 (Red Hat 4.3.2-7)
[quassnoi #] ./test
3.14159265358979323846264338327950288419716939937510582097494459230781640628620899
3.14159274101257324218750000000000000000000000000000000000000000000000000000000000
^
3.14159265358979311599796346854418516159057617187500000000000000000000000000000000
^
3.14159265358979311599796346854418516159057617187500000000000000000000000000000000
^
0000000001111111
1234567890123456
Ответ 2
Когда я изучал ответ Quassnoi, мне показалось подозрительным, что long double
и double
заканчиваются с одинаковой точностью, поэтому я немного покопался. Если я запускаю его код, скомпилированный с помощью clang, я получаю те же результаты, что и он. Однако я обнаружил, что если я указал long double
суффикс и использовал литерал для инициализации long double
суффикса, это обеспечило бы большую точность. Вот моя версия его кода:
#include <stdio.h>
int main(int argc, char** argv)
{
long double pild = 3.14159265358979323846264338327950288419716939937510582097494459230781640628620899L;
double pid = pild;
float pif = pid;
printf("%s\n%1.80f\n%1.80f\n%1.80Lf\n",
"3.14159265358979323846264338327950288419716939937510582097494459230781640628620899",
pif, pid, pild);
return 0;
}
И результаты:
3.14159265358979323846264338327950288419716939937510582097494459230781640628620899
3.14159274101257324218750000000000000000000000000000000000000000000000000000000000
^
3.14159265358979311599796346854418516159057617187500000000000000000000000000000000
^
3.14159265358979323851280895940618620443274267017841339111328125000000000000000000
^
Ответ 3
6 мест и 14 мест .1 место более 0 для 3, а последнее место, хотя и сохраненное, не может считаться точкой точности.
И извините, но я не знаю, что означает расширенные средства без дополнительного контекста. Вы имеете в виду С# decimal?
Ответ 4
Печать и подсчет, рождение ребенка, печать и подсчет. (Или прочитайте спецификации.)
Ответ 5
В модуле x86 с плавающей точкой (x87) есть инструкции для загрузки определенных констант с плавающей точкой. "fldz" и "fld1" загружают 0.0 и 1.0, например, на вершину стека "st" (иначе "st (0)"). Еще один "Fldpi".
Все эти значения имеют мантиссу длиной 64 бита, что означает почти 20 десятичных цифр. 64-битные значения возможны благодаря 80-битному временному формату с плавающей запятой, который используется внутри x87. X87 может загружать временные файлы и сохранять их в 10-байтовых ячейках памяти.
Ответ 6
Точность типа с плавающей запятой не связана с PI или какими-либо конкретными числами. Это зависит только от того, сколько цифр хранится в памяти для этого конкретного типа.
В случае IEEE-754 с float
используется 23 бита мантиссы, поэтому он может иметь точность до 23 + 1 бит точности или ~ 7 цифр точности в десятичном формате. Независимо от π, e, 1.1, 9.87e9... все они хранятся с ровно 24 битами в float. Аналогично double
(53 бита мантиссы) может хранить 15 ~ 17 десятичных цифр точности.
Ответ 7
Мир PI имеет PI до 100 000 000 000 цифр, вы можете просто распечатать и сравнить. Для немного более легкой для чтения версии Радость PI содержит 10 000 цифр. И если вы хотите запомнить цифры, вы можете попробовать прочесть стихотворение Cadaeic Cadenza.
Ответ 8
Для кода C просмотрите определения в <float.h>
. Это охватывает определения float
(FLT_*
), double
(DBL_*
) и long double
(LDBL_*
).
Ответ 9
* РЕДАКТИРОВАТЬ: см. Этот пост для актуальной дискуссии: Реализация sinpi() и cospi() с использованием стандартной математической библиотеки C *
Новые функции math.h __sinpi()
и __cospi()
исправили проблему для прямых углов, таких как 90 градусов и тому подобное.
cos(M_PI * -90.0 / 180.0) returns 0.00000000000000006123233995736766
__cospi( -90.0 / 180.0 ) returns 0.0, as it should
/* __sinpi(x) returns the sine of pi times x; __cospi(x) and __tanpi(x) return
the cosine and tangent, respectively. These functions can produce a more
accurate answer than expressions of the form sin(M_PI * x) because they
avoid any loss of precision that results from rounding the result of the
multiplication M_PI * x. They may also be significantly more efficient in
some cases because the argument reduction for these functions is easier
to compute. Consult the man pages for edge case details. */
extern float __cospif(float) __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_NA);
extern double __cospi(double) __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_NA);
extern float __sinpif(float) __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_NA);
extern double __sinpi(double) __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_NA);
extern float __tanpif(float) __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_NA);
extern double __tanpi(double) __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_NA);
Ответ 10
Поскольку существуют ситовые уравнения для двоичных представлений pi, можно объединить переменные для хранения кусков значения для повышения точности. Единственным ограничением точности этого метода является преобразование из двоичного в десятичное, но даже рациональные числа могут столкнуться с проблемами с этим.