Пи в си шарпе
Как вычислить PI в C#?
Как я могу вычислить значение PI, используя C#?
Я думал, что это будет через рекурсивную функцию, если да, то как она будет выглядеть и есть ли какие-либо математические уравнения для ее поддержки?
Я не слишком привередлив в отношении производительности, главным образом, как это сделать с точки зрения обучения.
21 Ответов
Если вы хотите рекурсию:
Это стало бы, после некоторого переписывания:
Исаак Ньютон (возможно, вы слышали о нем раньше 😉 ) придумал этот трюк. Обратите внимание, что я опустил конечное условие, чтобы оно было простым. В реальной жизни он тебе вроде как нужен.
Как насчет использования:
Если вы хотите получить более высокую точность, вам нужно будет использовать алгоритмическую систему и десятичный тип.
Если вы внимательно посмотрите на это действительно хорошее руководство:
Вы найдете на странице 70 эту милую реализацию (с незначительными изменениями с моей стороны):
Есть пара очень, очень старых трюков, которые я удивляюсь, что не вижу здесь.
atan(1) == PI/4, таким образом, старый каштан, когда надежная функция дуги-тангенса является настоящее — это 4*atan(1).
Очень симпатичная оценка с фиксированным коэффициентом, которая делает старый вестерн 22/7 похожим на грязь is 355/113,, что хорошо для нескольких десятичных знаков (по крайней мере, три или четыре, я думаю). В некоторых случаях этого даже достаточно для целочисленной арифметики: умножьте на 355, а затем разделите на 113.
355/113 также легко запомнить (во всяком случае, для некоторых людей): сосчитайте один, один, три, три, пять, пять и помните, что вы называете цифры в знаменателе и числителе (если вы забудете, какой триплет идет сверху, мысль микросекунды обычно выправит его).
Обратите внимание, что 22/7 дает вам: 3.14285714, что неверно в тысячных долях.
355/113 дает вам 3.14159292, что не является неправильным до десяти миллионных долей.
Аккумулятор. to /usr/include/math.h на моей коробке, M_PI — это #define’d как: 3.14159265358979323846 что, вероятно, хорошо, насколько это возможно.
Урок, который вы получаете от оценки PI, заключается в том, что есть много способов сделать это, ни один из них никогда не будет совершенным, и вы должны рассортировать их по назначению.
355/113 — это старая китайская оценка, и я считаю, что она предшествует 22/7 на много лет. Этому меня научил профессор физики, когда я был еще студентом.
Хороший обзор различных алгоритмов:
Я не уверен в сложности, заявленной для алгоритма Gauss-Legendre-Salamin в первой ссылке(я бы сказал O(N log^2(N) log(log (N))).
Я действительно призываю вас попробовать это, хотя конвергенция действительно быстрая.
Кроме того, я не совсем уверен, зачем пытаться преобразовать довольно простой процедурный алгоритм в рекурсивный?
Обратите внимание, что если вы заинтересованы в производительности, то работаете с ограниченной точностью (как правило, требуется ‘double’, ‘float’. вывод) на самом деле не имеет смысла, так как очевидный ответ в таком случае-просто жестко закодировать значение.
Как использовать константу PI в C++
Я хочу использовать константу PI и тригонометрические функции в некоторых программах на C++. Я получаю тригонометрические функции с include . Однако в этом заголовочном файле, похоже, нет определения для PI.
Как я могу получить PI, не определяя его вручную?
17 ответов:
на некоторых (особенно старых) платформах (см. комментарии ниже) вам может понадобиться
и затем включите необходимый файл заголовка:
и значение 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).
Проверьте boost documentation для получения дополнительных примеров.
получить его от Блока FPU на чипе вместо этого:
Я бы рекомендовал просто ввести pi с нужной вам точностью. Это не добавит времени вычисления к вашему выполнению, и оно будет переносимым без использования каких-либо заголовков или #defines. Вычисление acos или atan всегда дороже, чем использование предварительно вычисленного значения.
вместо того, чтобы писать
Я бы рекомендовал использовать -D_USE_MATH_DEFINES или /D_USE_MATH_DEFINES в зависимости от вашего компилятора.
таким образом, вы уверены, что даже в случае кого-то, включая заголовок, прежде чем вы это сделаете (и без #define), у вас все равно будут константы вместо неясной ошибки компилятора, которую вы будете отслеживать целую вечность.
поскольку официальная стандартная библиотека не определяет константу PI, вам придется определить ее самостоятельно. Итак, ответ на ваш вопрос «Как я могу получить PI, не определяя его вручную?»is» вы не . Или вы полагаетесь на некоторые расширения, специфичные для компилятора.». Если вы не беспокоитесь о переносимости, вы можете проверить руководство вашего компилятора для этого.
C++ позволяет писать
но инициализация этой константы не гарантируется статичностью. Этот Однако компилятор G++ обрабатывает эти математические функции как внутренние и может вычислить это постоянное выражение во время компиляции.
стандартный C++ не имеет константы для PI.
многие компиляторы C++ определяют M_PI на cmath (или math.h для C) как нестандартное расширение. Возможно, вам придется #define _USE_MATH_DEFINES прежде чем вы можете увидеть его.
Я ненабрав π с необходимой точностью. Что это значит? Элемент точность вам нужна точность T , но мы ничего не знаем о T .
можно сказать:о чем ты говоришь? T будет float , double или long double . Итак, просто введите точность long double , то есть
но вы действительно знаете, что в будущем в стандарте не будет нового типа с плавающей запятой с еще более высокой точностью, чем long double ? А ты нет.
и именно поэтому первое решение красиво. Вы можете быть совершенно уверены, что стандарт перегрузит тригонометрические функции для нового типа.
и, пожалуйста, не говорите, что оценка тригонометрической функции при инициализации производительности штраф.
Я вообще предпочитаю определять свой собственный: const double PI = 2*acos(0.0); потому что не все реализации предоставляют его для вас.
вопрос о том, вызывается ли эта функция во время выполнения или статична во время компиляции, обычно не является проблемой, потому что это происходит только один раз в любом случае.
Я использую следующее в одном из моих общих заголовков в проекте, который охватывает все базы:
на боковой ноте все нижеприведенные компиляторы определяют константы M_PI и M_PIl, если вы включаете . Нет необходимости добавлять ‘ #define _USE_MATH_DEFINES, который требуется только для VC++.
Я только что наткнулся в этой статье by Дэнни Калев который имеет большой совет для C++14 и выше.
Я думал, что это было довольно круто (хотя я бы использовал самую высокую точность PI там я мог), особенно потому, что шаблоны могут использовать его на основе типа.
на windows (cygwin + g++), я нашел необходимым добавить флаг -D_XOPEN_SOURCE=500 для препроцессора для обработки определения M_PI in math.h .
C++14 позволяет сделать static constexpr auto pi = acos(-1);
Арифметические и логические операции в Си-шарп
В этом уроке мы поговорим об арифметических и логических операциях, без которых сложно представить любую программу.
Все операции делятся на два типа: унарные и бинарные. К унарным относятся операции, в которых участвует один операнд. В бинарных операциях – два операнда. Операнд – это данные, которые принимают участие в операции. Например, оператор сложения «+» – бинарный 2+3, здесь операндами являются числа 2 и 3. Список бинарных арифметических операций приведен в таблице:
При делении двух целых чисел результатом также будет целое число. Например при делении 9/5 результатом будет число 1. Чтобы получить точный результат с десятичной точкой, нужно чтобы делимое и/или делитель были типа float или double. Например, при делении 9 / 5f (суффикс f указывает, что данная константа типа float) результатом будет 1.8.
Оператор «%» возвращает остаток от деления. Результатом операции 9 % 5 будет 4. Примером применения оператора «%» может быть процесс проверки числа на четность. Для этого мы ищем остаток от деления числа на 2. Если число четное, результатом будет 0, если нечетное – 1.
Чтобы повысить приоритет операции, используются скобки, как и в обычной арифметике.
При использовании оператора «+» для строк, он выполняет операцию конкатенации. Конкатенация – объединение нескольких объектов (например строк) в один.
static void Main(string[] args)
<
string str1 = «Hello», str2 = «World»;
Console.WriteLine(str1 + «, » + str2); //выводит на экран «Hello, World»
>
Унарные операторы в Си-шарп
Унарных арифметических операторов в Си-шарп есть всего два: инкрементация «++» и декрементация «—»;
Инкрементация увеличивает операнд на единицу, а декрементация — уменьшает на единицу.
static void Main(string[] args)
<
int a = 0, b = 5;
a++; // a=1;
b—; // b=4
>
Инкрементация и декрементация может быть префиксной и постфиксной. При Префиксной форме оператор стоит перед операндом, а при постфиксной-после.
Префиксная форма сначала увеличивает(уменьшает) значение, и после этого выполняются остальные действия, а при постфиксной форме наоборот — сначала выполнятся все действия, а после увеличится(уменьшится) значение:
static void Main(string[] args)
<
int a = 2, b = 3, c, d = 3;
c = a + ++b; // c = 6, сначала инкремент, потом сложение
с = a + d++; // c = 5, сначала сложение, потом инкремент
>
Везде где можно использовать инкрементацию/декрементацию стоит это делать, так как она работает быстрее оператора сложения/вычитания.
В Си-шарп также есть возможность использования краткой формы выражения:
static void Main(string[] args)
<
int a = 2, b = 3;
a += b; // равноценно выражению a = a + b;
a -= b; // равноценно выражению a = a — b;
a *= b; // равноценно выражению a = a * b;
a /= b; // равноценно выражению a = a / b;
a %= b; // равноценно выражению a = a % b;
>
Класс Math
В классе Math собраны все основные тригонометрические функции, функция возведение числа в степень, нахождение квадратного корня и другие.
Для возведения числа в степень, используется функция Pow([число], [степень]);
static void Main(string[] args)
<
float a, b = 9;
a = (float) Math.Pow(b, 2); // возводим переменную b в степень 2. Pow() возвращает результат в типе данных double, поэтому мы тут применили явное преобразование. Конечно, можно было обойтись без преобразования, объявив переменную a типа double
Console.WriteLine(a); // выводит на экран число 81
Console.ReadKey();
>
Для нахождения квадратного корня служит функция Sqrt([число]); возвращаемый результат также в типе данных double
static void Main(string[] args)
<
double a, b = 9;
a = Math.Sqrt(b);
Console.WriteLine(a); // выводит на экран число 3
Console.ReadKey();
>
Для нахождения косинуса и синуса используются cos([угол в радианах]) и sin([угол в радианах]) соответственно.
180 [градусов] = пи [радиан].
Чтобы перевести градусы в радианы, необходимо значение в градусах умножить на Пи и разделить на 180. Число Пи объявлено константой в классе Math.
static void Main(string[] args)
<
double a;
a = Math.Cos(60 * Math.PI / 180); // переводим 60 градусов в радианы
Console.WriteLine(a); // выводит на экран 0.5
a = Math.Sin(60 * Math.PI / 180);
Console.WriteLine(a); // выводит на экран 0.866…
Console.ReadKey();
>
Логические операторы в Си-шарп
Логические операторы в Си-шарп служат для работы с логическим типом данных (bool), который может принимать только два значения – true или false. Их можно разделить на две категории: простые логические операторы и операторы сравнения.
В Си-шарп есть следующие логические операторы:
! – оператор «НЕ» является унарным и возвращает противоположное значение операнда.
static void Main(string[] args)
<
bool a, b = true, c = false;
a = !b; // a = false
a = !c; // a = true
>
|| — оператор «ИЛИ» является бинарным и возвращает false только тогда, когда оба операнда равны false, в остальных случаях результат будет true;
static void Main(string[] args)
<
bool a, bTrue = true, bFalse = false;
a = bFalse || bFalse; // a = false
a = bFalse || bTrue; // a = true
a = bTrue || bFalse; // a = true
a = bTrue || bTrue; // a = true
>
static void Main(string[] args)
<
bool a, bTrue = true, bFalse = false;
a = bFalse && bFalse; // a = false
a = bFalse && bTrue; // a = false
a = bTrue && bFalse; // a = false
a = bTrue && bTrue; // a = true
>
Как вычислить PI в C#?
Как я могу вычислить значение PI с помощью C#?
Я думал, что это будет через рекурсивную функцию, если да, то как это будет выглядеть и есть какие-то математические уравнения, чтобы поддержать это?
Я не слишком разборчив в производительности, в основном, как это сделать с точки зрения обучения.
21 ответов
Если вы хотите рекурсии:
это станет, после некоторого переписывания:
Исаак Ньютон (вы, возможно, слышали о нем раньше ;)) придумал этот трюк. Обратите внимание, что я опустил конечное условие, чтобы оно было простым. В реальной жизни он тебе нужен.
Если вы хотите лучшую точность, чем это, вам нужно будет использовать алгоритмическую систему и десятичный тип.
есть несколько очень, очень старое, Я удивлен, что не вижу здесь.
atan (1) = = PI/4, поэтому старый каштан, когда надежная функция дуги-тангенса присутствует 4 * atan (1).
очень симпатичная оценка с фиксированным коэффициентом, которая делает старый Western 22/7 похожим на грязь это 355/113, что хорошо для нескольких десятичных знаков (по крайней мере, три или четыре, я думаю). В некоторых случаях это даже достаточно хорошо для целочисленной арифметики: умножить на 355, а затем разделить на 113.
355/113 также легко зафиксировать в памяти (для некоторых людей, во всяком случае): сосчитайте один, один, три, три, пять, пять и помните, что вы называете цифры в знаменателе и числителе (если вы забудете, какой триплет идет сверху, мысль микросекунды обычно собирается выпрямить его).
обратите внимание, что 22/7 дает вам: 3.14285714, что неверно в тысячных.
355/113 дает вам 3.14159292, который не ошибается, пока десять-милионной.
Acc. to / usr / include / math.h на моем поле, M_PI #define’D как: 3.14159265358979323846 что, вероятно, хорошо, насколько это происходит.
урок, который вы получаете от оценки PI, заключается в том, что есть много способов сделать это, никто никогда не будет совершенным, и вы должны сортировать их по предназначению.
355/113-это старая китайская оценка, и я считаю, что она датируется 22/7 многими годами. Этому меня научил профессор физики, когда я был старшекурсник.
Если вы внимательно посмотрите на это действительно хорошее руководство:
вы найдете на странице 70 эту милую реализацию (с небольшими изменениями с моей стороны):
хороший обзор различных алгоритмов:
Я не уверен в сложности, заявленной для алгоритма Гаусса-Лежандра-Саламина в первой ссылке(я бы сказал O(N log^2(N) log(log (N)))).
Я призываю вас попробовать, хотя конвергенция действительно быстро.
кроме того, я не совсем уверен, почему пытаюсь преобразовать довольно простой процедурный алгоритм в рекурсивный?
обратите внимание, что если вас интересует производительность, то работа с ограниченной точностью (как правило, требуется «двойной», «float». выходной) на самом деле не имеет смысла, так как очевидный ответ в таком случае просто жестко закодировать значение.
вот статья о вычислении PI в C#:
Что такое 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, которое достаточно хорошо для большинства инженерных целей.
Ввод-вывод в Си
Основной задачей программирования является обработка информации, поэтому любой язык программирования имеет средства для ввода и вывода информации. В языке Си нет операторов ввода-вывода.
Ввод и вывод информации осуществляется через функции стандартной библиотеки. Прототипы рассматриваемых функций находятся в файле stdio.h . Эта библиотека содержит функции
- printf() — для вывода информации
- scanf() — для ввода информации.
Вывод информации
Функция printf() предназначена для форматированного вывода. Она переводит данные в символьное представление и выводит полученные изображения символов на экран. При этом у программиста имеется возможность форматировать данные, то есть влиять на их представление
на экране.
Общая форма записи функции printf() :
СтрокаФорматов состоит из следующих элементов:
- управляющих символов;
- текста, представленного для непосредственного вывода;
- форматов, предназначенных для вывода значений переменных различных типов.
Объекты могут отсутствовать.
Управляющие символы не выводятся на экран, а управляют расположением выводимых символов. Отличительной чертой управляющего символа является наличие обратного слэша ‘’ перед ним.
Основные управляющие символы:
- ‘n’ — перевод строки;
- ‘t’ — горизонтальная табуляция;
- ‘v’ — вертикальная табуляция;
- ‘b’ — возврат на символ;
- ‘r’ — возврат на начало строки;
- ‘a’ — звуковой сигнал.
Форматы нужны для того, чтобы указывать вид, в котором информация будет выведена на экран. Отличительной чертой формата является наличие символа процент ‘%’ перед ним:
- %d — целое число типа int со знаком в десятичной системе счисления;
- %u — целое число типа unsigned int ;
- %x — целое число типа int со знаком в шестнадцатеричной системе счисления;
- %o — целое число типа int со знаком в восьмеричной системе счисления;
- %hd — целое число типа short со знаком в десятичной системе счисления;
- %hu — целое число типа unsigned short ;
- %hx — целое число типа short со знаком в шестнадцатеричной системе счисления;
- %ld — целое число типа long int со знаком в десятичной системе счисления;
- %lu — целое число типа unsigned long int ;
- %lx — целое число типа long int со знаком в шестнадцатеричной системе счисления;
- %f — вещественный формат (числа с плавающей точкой типа float );
- %lf — вещественный формат двойной точности (числа с плавающей точкой типа double );
- %e — вещественный формат в экспоненциальной форме (числа с плавающей точкой типа float в экспоненциальной форме);
- %c — символьный формат;
- %s — строковый формат.
Строка форматов содержит форматы для вывода значений. Каждый формат вывода начинается с символа % . После строки форматов через запятую указываются имена переменных, которые необходимо вывести.
Количество символов % в строке формата должно совпадать с количеством переменных для вывода. Тип каждого формата должен совпадать с типом переменной, которая будет выводиться на это место. Замещение форматов вывода значениями переменных происходит в порядке их следования.
Пример на Си
Результат работы программы
Тот же самый код может быть представлен с использованием одного вызова printf :
Табличный вывод
При указании формата можно явным образом указать общее количество знакомест и количество знакомест, занимаемых дробной частью:
В приведенном примере 10 — общее количество знакомест, отводимое под значение переменной; 5 — количество позиций после разделителя целой и дробной части (после десятичной точки). В указанном примере количество знакомест в выводимом числе меньше 10, поэтому свободные знакоместа слева от числа заполняются пробелами. Такой способ форматирования часто используется для построения таблиц.
Ввод информации
Функция форматированного ввода данных с клавиатуры scanf() выполняет чтение данных, вводимых с клавиатуры, преобразует их во внутренний формат и передает вызывающей функции. При этом программист задает правила интерпретации входных данных с помощью спецификаций форматной строки.
Общая форма записи функции scanf( ) :
Строка форматов аналогична функции printf() .
Для формирования адреса переменной используется символ амперсанд ‘&’ :
адрес = &объект
Строка форматов и список аргументов для функции обязательны.
Результат работы программы:
Функция scanf( ) является функцией незащищенного ввода, т.к. появилась она в ранних версиях языка Си. Поэтому чтобы разрешить работу данной функции в современных компиляторах необходимо в начало программы добавить строчку
Другой вариант — воспользоваться функцией защищенного ввода scanf_s( ) , которая появилась несколько позже, но содержит тот же самый список параметров.