Как определить значение PI? Каковы последствия использования различных определений PI? Будет ли достаточно объявления переменных как long double для PI_b, float для PI и PI_a? Могут ли быть изменения в результатах в зависимости от того, какое определение используется в программе?
Спасибо.
#ifdef M_PI
#define PI M_PI
#else
#define PI 3.14159265358979323846264338327950288420
#endif
//OR
#define PI_a 3.14159265358979323846
//OR
#define PI_b 3.14159265358979323846264338327950288420 /* 3 more than LDBL_DECIMAL_DIG */
@TomKarzes, это зависит от вашей реализации C. Спецификация языка не требует math.h или любого другого заголовка стандартной библиотеки для предоставления макроса или внешней переменной, передающей значение Pi.
Без дополнительной подробной информации о варианте использования это вопрос мнений. Как уже демонстрируют существующие ответы.
Думаю, это зависит от твоей цели, @TomKarzes. Я не считаю, что ОП запрашивает конкретную последовательность цифр, поскольку они уже представляют соответствующие последовательности цифр. Мне кажется довольно ясным, что вопрос в более широком смысле заключается в том, как использовать значение Pi в исходном коде C, и особенно в том, как определить макрос для его представления.
@Yunnosch ОП с трудом представляет себе последствия «недостаточного указания» значения числа пи как константы. Существующие ответы пытаются продемонстрировать, что для практических целей 7-8 цифр - это элегантная достаточность, и больше, вероятно, было бы излишним... Жаль, что другие предлагают "точность до 40-го десятичного знака", когда значения, видимые пользователями, будут округлить до 2-3 знаков после запятой...
@ Fe2O3 Да. это ваше мнение, хотя вы заметили, что существуют и другие мнения. Я думаю, вы поддерживаете мою точку зрения...
@JohnBollinger Да, это может быть правдой. Но арифметика с плавающей запятой по своей природе нестабильна. Даже для идентичных определений PI такие вещи, как флаги оптимизации, архитектура ЦП и т. д., могут изменить результаты с плавающей запятой. Многие процессоры имеют внутренние регистры с плавающей запятой, размер которых превышает 64 бита, и при использовании для операций с плавающей запятой результаты могут отличаться от результатов, которые можно было бы получить в чистой 64-битной реализации IEEE.
Согласен, @TomKarzes, хотя я думаю, что эти факторы выходят за рамки того, что задает вопрос.
@Yunnosch Я запутался в математическом классе (десятилетия назад), который пытался объяснить, что истинная математическая точность любого расчета проистекает из точности наименее точного значения в расчете ... Если, например, датчик выдает 16-битное чтение (скажем, 0-65535), имеющее дополнительные 30 цифр точности числа пи... что это за слово??? ах, да... перебор... (или, может быть, "глупый")... Просто мнение...
У людей были противоречивые мнения по этому поводу всякий раз, когда я публиковал код для проверки. Одни советовали мне использовать около сорока знаков после запятой, другие говорили, что это глупо и глупо. Спасибо за ваш ответ @ Fe2O3.
Википедия «Арифметика с плавающей запятой»: «Результат округления отличается от истинного значения примерно на 0,03 части на миллион и соответствует десятичному представлению π в первых 7 цифрах». ... Это поплавок одинарной точности - 7 десятичных цифр. Я думаю, что double занимает это до 14 или 16 десятичных цифр... Конечно, "длинный двойной" будет выше... Но, если вы вычисляете грех угла, будете ли вы, практически говоря, иметь значение для угол с точностью до 10^-16 радиан??? Я не могу представить никого, кто бы это сделал!! Некоторые здесь думают, что вычисление миллионной цифры числа Пи имеет практическое значение.
«Сколько цифр» Прочтите эту статью о Лоренце и происхождении «Теории хаоса»...cantorsparadise.com/… Еще один DV для моего ответа сегодня. Кажется, есть те, кто не очень понимает математику...





Как определить значение PI?
Это зависит от ваших целей.
Может ли быть изменение результатов в зависимости от того, какое определение используется в программа?
В общем, абсолютно. Насколько это вероятно, зависит от деталей типов с плавающей запятой вашей реализации C, конкретных форм используемых вами констант, характера и деталей вычисления и того, насколько точно вы выражаете результаты.
С вашими конкретными примерами вряд ли. Подробности читайте дальше.
Каковы эффекты от использования различные определения PI? Объявление переменных как long double достаточно для PI_b, float для PI и PI_a?
Во-первых, редко бывает веская причина для использования float, кроме как для минимизации размера хранилища. Современные процессоры не страдают от снижения производительности при использовании doubles — на самом деле вычисления с doubles могут быть немного быстрее, чем вычисления с floats.
Во-вторых, типы переменных, которым вы назначаете плавающие константы, — не единственное важное соображение.
Поскольку вы поднимаете вопросы о типе данных и вариации результатов и даете оценки Pi для большого количества десятичных цифр, я делаю вывод, что вы ищете наиболее точные оценки Pi, поддерживаемые различными доступными типами данных с плавающей запятой, и как использовать их в своих программах.
В этом случае важно понимать, что числовым константам присваиваются типы данных на основе их лексической формы, и это определяет их точность. Независимо от того, сколько цифр вы указываете, десятичная константа с плавающей запятой имеет тип double, если она без суффикса, тип float, если она имеет суффикс f или F, или тип long double, если она имеет суффикс l или L. Точность результата ограничена типом данных, независимо от того, сколько цифр вы записываете.
В частности, ваши числовые определения макросов PI, PI_a и PI_b расширяются до плавающих констант типа double. Все они имеют более чем достаточно значащих десятичных цифр, чтобы полностью определить все биты double типичной реализации C, а начальные цифры одинаковы, поэтому в такой реализации все они выражают одно и то же значение double. Вы можете присвоить это значение переменной типа long double, но это не приведет к автоматическому преобразованию его в более точную оценку.
Если вам нужна плавающая константа, выражающая оценку числа Пи с более высокой точностью, чем может вместить double, вам нужно использовать константу long double. Например,
// Note the 'L' suffix making this a long double constant:
#define PI_l 3.14159265358979323846264338327950288420L
Однако обратите внимание, что действительно ли long double обеспечивает большую точность, чем double, зависит от реализации, и даже среди тех, которые это делают, не все long double, которые вы можете встретить, точны до 38 десятичных цифр вашей константы.
Рассмотрим эту программу:
#include <stdio.h>
#define PI_l 3.14159265358979323846264338327950288420L
int main(void) {
// The type casts produce effects equivalent to assigning to a
// variable of the specified type and then reading back its value:
printf("As float: %.24f\n", (float) PI_l);
printf("As double: %.24f\n", (double) PI_l);
printf("As long double: %.24Lf\n", PI_l);
}
Для меня его выход
As float: 3.141592741012573242187500
As double: 3.141592653589793115997963
As long double: 3.141592653589793238512809
Обратите внимание, что все три отличаются друг от друга, и что даже версия long double расходится в цифре 20th от выражения константы в исходном коде.
Сколько операций потребуется, прежде чем врожденная числовая ошибка перерастет в значащие цифры, которые могут «испортить» результаты, напечатанные с точностью до 1/100?
Обычно много @ Fe2O3, поэтому «это зависит от ваших целей». С другой стороны, возможно, всего один, в зависимости от входных данных. Я ответил на вопрос, который, как я понимаю, задал ОП. Является ли это хорошим или уместным вопросом, это совершенно другой вопрос.
Если вы хотите
long double, то3.141592653589793238462643383279502884L. Обратите внимание на суффиксL.