Как сделать число пи в c

Добавил пользователь Алексей Ф.
Обновлено: 18.09.2024

создаю поток, следующим образом

при компиляции выдает
Description Resource Path Location Type
initializing argument 3 of 'int pthread_create(pthread_t*, const pthread_attr_t*, void* (*)(void*), void*)' threads.cc /threads line 50 C/C++ Problem

pi_calc -фунция подсчета числа, проверил даже на примере из справки,не рабтает,
т.е.

Posted via ActualForum NNTP Server 1.5

Posted via ActualForum NNTP Server 1.5

ГДЕ ты хочешь увидеть результат функции?
Тем более, что ты вызываешь

А что тут объяснять.

Вот вы N раз создаете потоки, передавая в них t_num[i]:

А ваши потоки игнорируют переданный параметр и каждый из них вычисляет некое значение не зависящее от внешних параметров, т.е. они делают одно и то же.

Николай Капустин

Баин правильно подметил, но если тебе прям так нужно именно вводить Пи, то создаёшь переменную с плавающей точкой и уже в неё вводишь значение Пи(точнее считываешь строку, а уже её преобразуешь в "дробное")

Тимофей Белов


Тимофей Белов

Николай Капустин

Тимофей, говорит через библиотеки не получилось, либо он плохо искал(что 99% скорее правда), либо он пишет на каком-то "браинфаке"

Тимофей Белов


Тимофей Белов ответил Николаю

Николай Капустин

Тимофей, в него вообще никто не лезет, кроме чувака, который либо делает комп на лампах, либо тот, кто хочет затралить препода, который сказал "можете сделать на любом языке" :D

Тимофей Белов


Тимофей Белов

Никита Нестеров


Никита Нестеров

Тимофей Белов


Тимофей Белов ответил Никите

Никита Нестеров


Никита Нестеров ответил Тимофею

😂

Тимофей, согл, к тому же мой вариант писать гараздо дольше, постоянно, проще просто pi
Ну. Я думаю если нужно воспользоваться 1 раз, то мой будет короче, ибо занимать память под константу. Ну зачем?

Тимофей Белов


Тимофей Белов ответил Никите

ну я пишу конст, место занимаю один раз. константа статическая, ну я не думаю что скорость изменится))))))

Никита Нестеров


Никита Нестеров ответил Тимофею

Тимофей, не экономишь память


Юрий Максимов

Последовательная версия.

Давайте для начала сделаем последовательную версию. Т.е. такую, которая использует одно ядро обычного центрального процессора. Возьмем самый простой из методов численного инетгрирования — метод прямоугольников и закодим его на языке Си (вообще дальше будем пользоваться Си\С++-ным суржиком в виду ряда причин.
Объявим некоторое количество cntSteps прямоугольников на которые мы разобъем нашу площадь под интегралом, посчитаем основание:

и всю площадь, посчитав значение функии в каждом прямоугольнике и домножив на основание.

Вот полный код программы:

Native Threads

Ладно, давайти ближе к коду: с точки зрения языка Си поток — это обычная функция или метод класса, удовлетворяющая определённому прототипу. Давайте назовём ее static void * worker ( void * ptrArgs ) , аргументом она получает указатель на структуру, в которой можно сделать полей сколько нужно чтобы передать потоку его аргументы. В нашем случае мы скажем потоковой функии в каком диапазоне считать наш интеграл. В теле потоковой функции — уже известный нам цикл, собсно и считающий по диапазону который мы ему передали в параметрах.

Интервал интегрирования для каждого потока мы заранее вычислим изходя из его порядкового номера. Если один из потоков посчитает свою часть раньше — то соответсвующее ядро будет простаивать, т.е. мы потеряем производительность. Идеально было бы разделить интервал на много маленьих участков и раздавать потокам по мере того как они справляются со своей работой. Но пока оставим как есть.

На исполнение отдельным потоком функция запускается через системный вызов pthread_create в случае POSIX (в линуксе, например) или в случае windows этто будет аналогичный вызов из Win32 API, вуглядеть будет немного по-другому, но в целом похоже.

Результат будем из каждого потока прибавлять к общем перменной pi += sum * step ; (помним что мы находимся в общем адресном пространстве).


Итого выходит как-то так:

На самом деле конкретно в этом примере (но так везти будет не всегда) можно было обойтись без мьютексов вообще если сохранять в каждом потоке результат в отдельную переменную (элемент массива ArgsThread arrArgsThread [ cntThreads ];
) а потом, дождавшись завершения всех потоков — просуммировать что получилось.

Вот код без мьютексов:

Как видите, код получилася довольно громоздкий и некросплатформенный. Если последнее решается отчасти с помощью boost::threads(но не все хотят ставить boost) или в новом C++11 потоки вообще стали частью языка (очень здорово вышло на самом деле) — но большая часть софта пока еще использует старый C++. Но проблема громоздкости кода всё равно остается.

OpenMP

эта прагма говорит, что нужно распараллелить витки цикла, переменную x сделать приватной для каждого потока, по переменной sum потом провести редукцию (или как это по-русски?) по суммированию. Т.е. сначала создать для каждого потока по копии — а потом их сложить. Примерно то же самое, что мы сделали в прошлом примере без мьютекосв. Также OpenMP предоставляет небольшой API для сервисных нужд.

Я хочу использовать константу PI и тригонометрические функции в некоторой программе на С++. Я получаю тригонометрические функции с include . Однако в этом заголовочном файле не существует определения для PI.

Как я могу получить PI, не определяя его вручную?

Вы также можете использовать boost, который определяет важные математические константы с максимальной точностью для запрашиваемого типа (т.е. float vs double).

На некоторых (особенно старых) платформах (см. комментарии ниже) вам может понадобиться

а затем включить необходимый файл заголовка:

а значение pi можно получить через:

В моем math.h (2014) он определяется как:

но еще раз проверьте math.h . Выдержка из "старого" math.h (в 2009 году):

на новых платформах (по крайней мере, на моем 64-битном Ubuntu 14.04) мне не нужно определять _USE_MATH_DEFINES

В (недавних) платформах Linux есть значения long double , также предоставляемые как расширение GNU:

Pi можно рассчитать как atan(1)*4 . Вы можете вычислить значение таким образом и кешировать его.

Получите его от блока FPU на чипе вместо этого:

Я бы рекомендовал использовать -D_USE_MATH_DEFINES или /D_USE_MATH_DEFINES в зависимости от вашего компилятора.

Поскольку официальная стандартная библиотека не определяет константу PI, вам придется ее самостоятельно определить. Итак, ответ на ваш вопрос "Как я могу получить PI, не определяя его вручную?" msgstr "Нет - или вы полагаетесь на некоторые расширения для компилятора.". Если вы не заботитесь о переносимости, вы можете проверить это руководство для компилятора.

С++ позволяет писать

но инициализация этой константы не гарантируется как статическая. Компилятор g++, однако, обрабатывает эти математические функции как intrinsics и способен вычислять это постоянное выражение во время компиляции.

Стандарт С++ не имеет константы для PI.

Я бы не печатал в π точной точности. Что это значит? Точность, в которой вы нуждаетесь, - это точность T , но мы ничего не знаем о T .

Вы могли бы сказать: о чем вы говорите? T будет float , double или long double . Итак, просто введите точность long double , т.е.

Но знаете ли вы, что в будущем в стандарте не будет нового типа с плавающей точкой с еще большей точностью, чем long double ? Вы этого не делаете.

И вот почему первое решение красиво. Вы можете быть уверены, что стандарт перегрузит тригонометрические функции для нового типа.

И, пожалуйста, не говорите, что оценка тригонометрической функции при инициализации является штрафом за производительность.

Читайте также: