Как ввести пи в visual studio
Я думал, что это будет через рекурсивную функцию, если да, то как это будет выглядеть и есть какие-то математические уравнения, чтобы поддержать это?
Я не слишком разборчив в производительности, в основном, как это сделать с точки зрения обучения.
Если вы хотите рекурсии:
это станет, после некоторого переписывания:
Исаак Ньютон (вы, возможно, слышали о нем раньше ;)) придумал этот трюк. Обратите внимание, что я опустил конечное условие, чтобы оно было простым. В реальной жизни он тебе нужен.
Если вы хотите лучшую точность, чем это, вам нужно будет использовать алгоритмическую систему и десятичный тип.
есть несколько очень, очень старое, Я удивлен, что не вижу здесь.
atan (1) = = PI/4, поэтому старый каштан, когда надежная функция дуги-тангенса присутствует 4 * atan (1).
очень симпатичная оценка с фиксированным коэффициентом, которая делает старый Western 22/7 похожим на грязь это 355/113, что хорошо для нескольких десятичных знаков (по крайней мере, три или четыре, я думаю). В некоторых случаях это даже достаточно хорошо для целочисленной арифметики: умножить на 355, а затем разделить на 113.
355/113 также легко зафиксировать в памяти (для некоторых людей, во всяком случае): сосчитайте один, один, три, три, пять, пять и помните, что вы называете цифры в знаменателе и числителе (если вы забудете, какой триплет идет сверху, мысль микросекунды обычно собирается выпрямить его).
обратите внимание, что 22/7 дает вам: 3.14285714, что неверно в тысячных.
355/113 дает вам 3.14159292, который не ошибается, пока десять-милионной.
урок, который вы получаете от оценки PI, заключается в том, что есть много способов сделать это, никто никогда не будет совершенным, и вы должны сортировать их по предназначению.
355/113-это старая китайская оценка, и я считаю, что она датируется 22/7 многими годами. Этому меня научил профессор физики, когда я был старшекурсник.
Если вы внимательно посмотрите на это действительно хорошее руководство:
вы найдете на странице 70 эту милую реализацию (с небольшими изменениями с моей стороны):
хороший обзор различных алгоритмов:
Я не уверен в сложности, заявленной для алгоритма Гаусса-Лежандра-Саламина в первой ссылке(я бы сказал O(N log^2(N) log(log (N)))).
Я призываю вас попробовать, хотя конвергенция действительно быстро.
кроме того, я не совсем уверен, почему пытаюсь преобразовать довольно простой процедурный алгоритм в рекурсивный?
обратите внимание, что если вас интересует производительность, то работа с ограниченной точностью (как правило, требуется "двойной", "float". выходной) на самом деле не имеет смысла, так как очевидный ответ в таком случае просто жестко закодировать значение.
Что такое PI? Окружность круга, деленная на его диаметр.
в компьютерной графике вы можете построить / нарисовать круг с центром в 0,0 от начальной точки x, y, следующая точка x', y' можно найти с помощью простой формулы: x '= x + y / h: y' = y - x' / H
h обычно является степенью 2, так что деление можно легко сделать со сдвигом (или вычитанием из показателя на двойнике). h также хочет быть радиусом r вашего круга. Легкая точка отсчета быть x = r, y = 0, а затем считать c число шагов до x
рекурсия на любую большую глубину обычно непрактична для коммерческой программы, но хвостовая рекурсия позволяет алгоритму выражаться рекурсивно, а реализована как цикл. Рекурсивные алгоритмы поиска иногда могут быть реализованы с использованием очереди, а не стека процесса, поиск должен вернуться из тупика и принять другой путь - эти точки возврата можно поместить в очередь, и несколько процессов могут отменить очередь точек и попробовать другие пути.
вычислить следующим образом:
Это самый простой способ я знаю.
значение PI медленно сходится к фактическому значению Pi (3.141592165. ). Если вы повторяете больше раз, тем лучше.
вот хороший подход (от основная запись Википедии на pi); он сходится гораздо быстрее, чем простая формула, рассмотренная выше, и вполне поддается рекурсивному решению, если ваше намерение состоит в том, чтобы преследовать рекурсию как учебное упражнение. (Предполагая, что вы после опыта обучения, я не даю никакого фактического кода.)
базовая формула такая же, как и выше, но этот подход усредняет частичные суммы для ускорения конвергенция.
определите функцию двух параметров, pie (h, w), такую, что:
Итак, ваша первая возможность изучить рекурсию-это закодировать это" горизонтальное "вычисление по мере увеличения параметра "ширина" (для "высоты" нуля).
затем добавьте второе измерение с этой формулой:
, который используется, конечно, только для значений H больше нуля.
хорошая вещь об этом алгоритме заключается в том, что вы можете легко глумиться он с электронной таблицей, чтобы проверить ваш код, как вы исследуете результаты, полученные постепенно больших параметров. К тому времени, когда вы вычислите pie(10,10), у вас будет приблизительное значение для pi, которое достаточно хорошо для большинства инженерных целей.
Как определить число Пи в программе на языке C++? Стандартом языка эта константа не определена (но, возможно, появится в будущем).
Первая мысль — создать константу одного из вещественных типов. Сколько знаков после запятой нужно прописать? В стандарте языка определен класс-шаблон numeric_limits, с помощью которого можно узнать ограничения в том числе и вещественных типов языка. К примеру, значение std::numeric_limits::digits10 возвращает количество десятичных цифр, которое тип может представлять без потери точности.
На сегодня для типа float это 6, для типа double это 15, а для типа long double это 18. Последнее верно, только если long double имеет 80-битное представление. К примеру, в случае компилятора среды «Visual Studio Community 2017» для типа long double обсуждаемое количество равно 15, как и для типа double (источник), так как в этой системе тип long double имеет 64-битное представление и по сути является аналогом типа double.
Итак, первый способ определения числа Пи:
Строго говоря, в этой константе десятичных цифр 16 (одна до точки, 15 — после), но на практике (компилятор среды «Visual Studio Community 2017») именно в таком виде константа без потерь проходит, к примеру, цепочку преобразований «текст → double → текст». Если добавить, например, 16-ю цифру после точки, то после указанного преобразования она уже не сохранится.
Возможно, имеется какой-то практический смысл в том, чтобы указывать в обсуждаемой константе больше 15 цифр после запятой. Потому что в среде «Visual Studio Community 2017» определена константа M_PI, содержащая значение 3.14159265358979323846 (20 знаков после точки). Источник.
Третий способ определения числа Пи — с помощью одной из обратных тригонометрических функций. Например, с помощью арккосинуса:
Ну и на сладкое. Получение числа Пи с помощью ассемблерной вставки (отсюда):
Всё перечисленное проверено на «Windows 7 Профессиональная» (SP1), 64-разрядная. Компилятор среды «Visual Studio Community 2017».
I want to use the PI constant and trigonometric functions in some C++ program. I get the trigonometric functions with include . However, there doesn't seem to be a definition for PI in this header file.
How can I get PI without defining it manually?
Loosely related: see cise.ufl.edu/~manuel/obfuscate/pi.c on how to calculate value of PI directly from definition.
25 Answers 25
On some (especially older) platforms (see the comments below) you might need to
and then include the necessary header file:
and the value of pi can be accessed via:
In my math.h (2014) it is defined as:
but check your math.h for more. An extract from the "old" math.h (in 2009):
on newer platforms (at least on my 64 bit Ubuntu 14.04) I do not need to define the _USE_MATH_DEFINES
On (recent) Linux platforms there are long double values too provided as a GNU Extension:
Even after defining _USE_MATH_DEFINES if GCC complains that's because __STRICT_ANSI__ is defined (perhaps you passed -pedantic or -std=c++11 ) which disallows M_PI to be defined, hence undefine it with -D__STRICT_ANSI__ . When defining it yourself, since it's C++, instead of a macro you should constexpr auto M_PI = 3.14159265358979323846; .
Pi can be calculated as atan(1)*4 . You could calculate the value this way and cache it.
-1: Works only if atan(1)*4 == 3.141592653589793238462643383279502884 (roughly speaking). I wouldn't bet on it. Be normal and use a raw literal to define the constant. Why lose precision when you don't need to?
You could also use boost, which defines important math constants with maximum accuracy for the requested type (i.e. float vs double).
Check out the boost documentation for more examples.
@Gracchus: Yup. C++ without libraries (or without the new C++11 libraries) is, as much as I like that language and as much as I would like to code everything myself, not very productive.
I believe he said complexity not size. Presumably referring to a) the 3 nested namespaces, and b) defining pi as a templated function rather than just a normal constant.
C++20 std::numbers::pi
where the exact result was calculated with:
Compile and run:
Tested on Ubuntu 20.04 amd64, GCC 10.2.0
The accepted proposal describes:
5.0. “Headers” [headers] In the table [tab:cpp.library.headers], a new header needs to be added.
[. ]
I don't understand why the long double precision pi has only two more digits of accuracy than the double precision pi. That suggests that it's hardly worth using long double.
@Anachronist It could be a sign that on g++10, on your machine (like on mine), the long doubles are implemented as 80-bits extended precision, not quadruple precision.
Get it from the FPU unit on chip instead:
I love this answer. It is particularly useful when targeting older x86 platforms which is a small fad as of late where the optimizing compilers aren't as terribly involved as modern ones. Thanks for this Henrik!
Rather than writing
I would recommend using -D_USE_MATH_DEFINES or /D_USE_MATH_DEFINES depending on your compiler.
Good tip. If "you" are a compilation unit then of course you can ensure the macro is defined before anything is included. But if "you" are a header file, it's out of your control.
In fact even if "you" are a compilation unit. depending on the ordering of the headers is a the shortest path toward maintenance nightmare.
The very common issue in a project is that if you're compiling with Visual Studio for example you don't know in which order the compiler is going to go through your files so if you use
This is a great example why we should not take this approach, we people make mistakes, rounding, copy&pasting, etc. I think using M_PI is the right approach.
@nacho4d I too prefer M_PI if it's available, but not all systems are POSIX compliant. I think this approach is better than the 4*atan(1) method for the cases where M_PI is not available.
"Calculating acos or atan is always more expensive" is not true. Any modern optimizing compiler knows all about standard math functions and can constant-propagate through them. See e.g. goo.gl/BvdJyr
Since the official standard library doesn't define a constant PI you would have to define it yourself. So the answer to your question "How can I get PI without defining it manually?" is "You don't -- or you rely on some compiler-specific extensions.". If you're not concerned about portability you could check your compiler's manual for this.
C++ allows you to write
but the initialization of this constant is not guaranteed to be static. The G++ compiler however handles those math functions as intrinsics and is able to compute this constant expression at compile-time.
I usually use acos(-1), as you say, they are compile-time evaluated. When I tested M_PI, acos(-1) and atan(1)*4, I got identical values.
The traditional way is to use 4*atan(1.) : atan is easy to implement and multiplying by 4 is an exact operation. Of course, modern compilers fold (aim to fold) all constants with the required precision, and it's perfectly reasonable to use acos(-1) or even std::abs(std::arg(std::complex
Just so no one accidentally thinks you are serious (again-_-'). This is a terrible solution. The atan implementation is not defined by the standard meaning its implementation and possibly hw dependent. This means that the numerics can be terrible, meaning you may well be better off using 3.14 in general. Further its quite possibly slow, even for the special cases.
Standard C++ doesn't have a constant for PI.
I would not typing in π to the precision you need. What is that even supposed to mean? The precision you need is the precision of T , but we know nothing about T .
You might say: What are you talking about? T will be float , double or long double . So, just type in the precision of long double , i.e.
But do you really know that there won't be a new floating point type in the standard in the future with an even higher precision than long double ? You don't.
And that's why the first solution is beautiful. You can be quite sure that the standard would overload the trigonometric functions for a new type.
And please, don't say that the evaluation of a trigonometric function at initialization is a performance penalty.
Я хочу использовать константу PI и тригонометрические функции в некоторой программе на C++. Я получаю тригонометрические функции с include . Однако в этом заголовочном файле, похоже, нет определения для PI.
Как я могу получить PI без определения его вручную?
на некоторых (особенно старых) платформах (см. комментарии ниже) вам может потребоваться
а затем включите необходимый файл заголовка:
и значение pi можно получить через:
в своем math.h (2014) определяется как:
но проверить math.h дополнительные. Выдержка из "старого" math.h (в 2009 году):
на новых платформы (по крайней мере, на моем 64-битном Ubuntu 14.04) мне не нужно определять _USE_MATH_DEFINES
на (последних) платформах Linux есть long double значения также предоставляются как расширение GNU:
Pi можно вычислить как atan(1)*4 . Можно вычислить значение таким образом, и кэшировать его.
вы также можете использовать boost, который определяет важные математические константы с максимальной точностью для запрашиваемого типа (т. е. float vs double).
Проверьте увеличить документации для получения дополнительных примеров.
получите его от Блока FPU на обломоке вместо:
вместо того, чтобы писать
Я бы рекомендовал использовать -D_USE_MATH_DEFINES или /D_USE_MATH_DEFINES в зависимости от вашего компилятора.
поскольку официальная стандартная библиотека не определяет константу PI, вам придется определить ее самостоятельно. Итак, ответ на ваш вопрос "Как я могу получить PI без определения его вручную?"is" вы не . Или вы полагаетесь на некоторые расширения, специфичные для компилятора.". Если вы не беспокоитесь о переносимости, вы можете проверить руководство компилятора для этого.
C++ позволяет писать
но инициализация этой константы не гарантируется как статическая. Этот Однако компилятор G++ обрабатывает эти математические функции как встроенные и может вычислять это постоянное выражение во время компиляции.
стандартный C++ не имеет константы для PI.
Я не набрав π с необходимой точностью. Что это значит? The точность вам нужна точность T , но мы ничего не знаем о T .
можно сказать:о чем ты говоришь? T будет float , double или long double . Итак, просто введите точность long double , т. е.
но вы действительно знаете, что в будущем в стандарте не будет нового типа с плавающей запятой с еще более высокой точностью, чем long double ? Нет.
и именно поэтому первое решение красиво. Вы можете быть уверены, что стандарт перегрузит тригонометрические функции для нового типа.
и, пожалуйста, не говорите, что оценка тригонометрической функции при инициализации производительности штраф.
Я обычно предпочитаю определять свой собственный: const double PI = 2*acos(0.0); потому что не все реализации предоставляют его для вас.
вопрос о том, вызывается ли эта функция во время выполнения или статична во время компиляции, обычно не является проблемой, потому что это происходит только один раз.
Я использую следующее в одном из моих общих заголовков в проекте, который охватывает все базы:
Я только что наткнулся в этой статье by Дэнни Калев который имеет отличный совет для C++14 и выше.
Я думал, что это довольно круто (хотя я бы использовал самую высокую точность PI там я мог), особенно потому, что шаблоны могут использовать его на основе типа.
В windows (cygwin + g++) я нашел необходимым добавить флаг -D_XOPEN_SOURCE=500 для препроцессора для обработки определения M_PI на math.h .
Какой закон распределения имеет случайная величина означающая число извлеченных красных карандашей?
Помогите пожалуйста решить две задачи очень срочно надо решить!ничего не понимаю! 2) В коробке.
Какая константа отвечает за точку в GraphABC?
Какая из констант клавиш отвечает за точку в GraphABC?
Дано натуральное число. Если в нем есть а и в то определить какая правее
Дано натуральное число. Если в нем есть а и в то определить какая правее Добавлено через 2 часа.
расширения могут быть определены везде, но они не должны ничему соответствовать
их могут менять и в пределах одного компилятора, в разных его версиях
но самое главное, они могут называться одинаково, а значения разные иметь
и из-за этого в программе появляется неопределённость
accept, по-моему, вы придираетесь. Я лично не верю, что завтра выйдет новая версия моего любимого компилятора, и в ней будет
Да никто не спорит, что константа пи - не часть языка С/С++, но с вероятностью 99.(9)% она будет определена в math.h или во включаемом им заголовке и значению её удивляться не прийдётся.
да, можно определить её как 3.14 и ничего удивительного
просто в программе что-то там будет округляться совсем немного, и ракета полетит не туда чуть-чуть
accept, по-моему, вы придираетесь. Я лично не верю, что завтра выйдет новая версия моего любимого компилятора
программа должна быть переносимой, иначе не выйдет что-нибудь там когда-нибудь, и придётся её класть куда-нибудь очень далеко и надолго
ничто не мешает, но это не расширение
расширение может выглядеть одинаково, а работать по-разному
и читать инфу по каждому расширению, в каком компиляторе оно какое, да нафик это надо
понимаешь, вот есть функция strcpy() и вот она есть в стандарте, и хоть что там будут писать какие-нибудь компиляторы, предлагать перейти на похожую функцию, только чуть-чуть другую, да мне оно нафик не надо, потому что я стандарт прочитал, как она работает запомнил, и всё, я знаю где там и что, и поменяться оно может только в новом стандарте, который я естественно на этот счёт просканирую точно также, как первый
Читайте также: