Значение PI в C

Как определить значение 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 */

Если вы хотите long double, то 3.141592653589793238462643383279502884L. Обратите внимание на суффикс L.

Ted Lyngmo 02.10.2022 08:02

@TomKarzes, это зависит от вашей реализации C. Спецификация языка не требует math.h или любого другого заголовка стандартной библиотеки для предоставления макроса или внешней переменной, передающей значение Pi.

John Bollinger 02.10.2022 08:04

Без дополнительной подробной информации о варианте использования это вопрос мнений. Как уже демонстрируют существующие ответы.

Yunnosch 02.10.2022 08:07

Думаю, это зависит от твоей цели, @TomKarzes. Я не считаю, что ОП запрашивает конкретную последовательность цифр, поскольку они уже представляют соответствующие последовательности цифр. Мне кажется довольно ясным, что вопрос в более широком смысле заключается в том, как использовать значение Pi в исходном коде C, и особенно в том, как определить макрос для его представления.

John Bollinger 02.10.2022 08:15

@Yunnosch ОП с трудом представляет себе последствия «недостаточного указания» значения числа пи как константы. Существующие ответы пытаются продемонстрировать, что для практических целей 7-8 цифр - это элегантная достаточность, и больше, вероятно, было бы излишним... Жаль, что другие предлагают "точность до 40-го десятичного знака", когда значения, видимые пользователями, будут округлить до 2-3 знаков после запятой...

Fe2O3 02.10.2022 08:15

@ Fe2O3 Да. это ваше мнение, хотя вы заметили, что существуют и другие мнения. Я думаю, вы поддерживаете мою точку зрения...

Yunnosch 02.10.2022 08:19

@JohnBollinger Да, это может быть правдой. Но арифметика с плавающей запятой по своей природе нестабильна. Даже для идентичных определений PI такие вещи, как флаги оптимизации, архитектура ЦП и т. д., могут изменить результаты с плавающей запятой. Многие процессоры имеют внутренние регистры с плавающей запятой, размер которых превышает 64 бита, и при использовании для операций с плавающей запятой результаты могут отличаться от результатов, которые можно было бы получить в чистой 64-битной реализации IEEE.

Tom Karzes 02.10.2022 08:20

Согласен, @TomKarzes, хотя я думаю, что эти факторы выходят за рамки того, что задает вопрос.

John Bollinger 02.10.2022 08:23

@Yunnosch Я запутался в математическом классе (десятилетия назад), который пытался объяснить, что истинная математическая точность любого расчета проистекает из точности наименее точного значения в расчете ... Если, например, датчик выдает 16-битное чтение (скажем, 0-65535), имеющее дополнительные 30 цифр точности числа пи... что это за слово??? ах, да... перебор... (или, может быть, "глупый")... Просто мнение...

Fe2O3 02.10.2022 08:24

У людей были противоречивые мнения по этому поводу всякий раз, когда я публиковал код для проверки. Одни советовали мне использовать около сорока знаков после запятой, другие говорили, что это глупо и глупо. Спасибо за ваш ответ @ Fe2O3.

Haris 02.10.2022 09:47

Википедия «Арифметика с плавающей запятой»: «Результат округления отличается от истинного значения примерно на 0,03 части на миллион и соответствует десятичному представлению π в первых 7 цифрах». ... Это поплавок одинарной точности - 7 десятичных цифр. Я думаю, что double занимает это до 14 или 16 десятичных цифр... Конечно, "длинный двойной" будет выше... Но, если вы вычисляете грех угла, будете ли вы, практически говоря, иметь значение для угол с точностью до 10^-16 радиан??? Я не могу представить никого, кто бы это сделал!! Некоторые здесь думают, что вычисление миллионной цифры числа Пи имеет практическое значение.

Fe2O3 02.10.2022 09:56

«Сколько цифр» Прочтите эту статью о Лоренце и происхождении «Теории хаоса»...cantorsparadise.com/… Еще один DV для моего ответа сегодня. Кажется, есть те, кто не очень понимает математику...

Fe2O3 03.10.2022 22:44
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
12
159
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Как определить значение 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 02.10.2022 10:03

Обычно много @ Fe2O3, поэтому «это зависит от ваших целей». С другой стороны, возможно, всего один, в зависимости от входных данных. Я ответил на вопрос, который, как я понимаю, задал ОП. Является ли это хорошим или уместным вопросом, это совершенно другой вопрос.

John Bollinger 02.10.2022 17:06

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