Форум программистов, компьютерный форум CyberForum.ru

C++

Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 18, средняя оценка - 4.72
_nic
0 / 0 / 0
Регистрация: 04.05.2010
Сообщений: 112
#1

Как просчитать число ПИ до определенного знака? - C++

06.08.2010, 23:26. Просмотров 2274. Ответов 7
Метки нет (Все метки)

Подскажите удобную формулу.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
06.08.2010, 23:26     Как просчитать число ПИ до определенного знака?
Посмотрите здесь:
Подсчет элементов массива определенного знака C++
В целочисленном массиве найти число чередований знака, то есть число переходов с минуса на плюс или с плюса на минус. C++
C++ Как просчитать шаги от домов до магазина
Найти в массиве число чередований знака C++
Вывести на экран с точностью два знака число ПИ C++
В заданном массиве определите число соседств двух чисел разного знака C++
Обработать результаты замеров температур: найти минимум, число изменений знака C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Хохол
Эксперт C++
475 / 443 / 13
Регистрация: 20.11.2009
Сообщений: 1,292
06.08.2010, 23:33     Как просчитать число ПИ до определенного знака? #2
ru.wikipedia.org/wiki/Число_пи
Выбирайте по вкусу формулу, считайте по ней с нужной точностью.
abiprofi
48 / 48 / 2
Регистрация: 04.08.2010
Сообщений: 110
06.08.2010, 23:37     Как просчитать число ПИ до определенного знака? #3
Если речь идет об округлении до определенного знака, то примерно так:
Объявление функции:
C++
1
double __fastcall DRound(double Argument, int Precision);
Реализация:
C++
1
2
3
4
5
6
7
8
9
10
11
12
double __fastcall TForm1::DRound(double Argument, int Precision)
{
//Точность может быть отрицательной. Dround(1234,-2) = 1200.
 double Divisor  = 1.0;
 if(Precision >= 0)
  while(Precision--)
   Divisor *= 10.0;
 else
  while(Precision++)
   Divisor /= 10.0;
 return floor(Argument * Divisor + 0.5) / Divisor;
}
А формулы предложены абсолютно верно господином "Хохол"!
_nic
0 / 0 / 0
Регистрация: 04.05.2010
Сообщений: 112
06.08.2010, 23:38  [ТС]     Как просчитать число ПИ до определенного знака? #4
Где я тут ошибся:
C
1
2
3
4
5
6
7
8
9
10
11
12
13
__int64 leng=2;
    long double f4=4,f3=3;
    long double result=f4/f3,del=5;
    for(int i=0;i<leng;i++)
    {
        result=result+f4/del;
        del=del+2;
        result=result-f4/del;
        del=del+2;
    }
    long double x=4;
    cout<<x-result;
    getch();
?
abiprofi
48 / 48 / 2
Регистрация: 04.08.2010
Сообщений: 110
07.08.2010, 00:28     Как просчитать число ПИ до определенного знака? #5
Положить n=0, S1 = 0 и S2 = 0; ( начальные установки )
Увеличить n на 1; ( n становится нечетным )
Вычислить S1 = S2 + 4/(2n-1); (S1 - есть верхняя оценка )
Увеличить n на 1; ( n становится четным )
Вычислить S2 = S1 - 4/(2n-1); (S2 - есть нижняя оценка)
Если S1 - S2 >= 10^(-5) перейти к шагу 2;
( нужная точность еще не достигнута )
Напечатать результат (S1 + S2) / 2

Добавлено через 37 минут
Вот вспомнил. Код ни в коем случае не мой. Программист - француз Pascal Sebah.
Вычисляем первые NbDigits цифр числа Pi(в данном случае 10000). Используется рекурсия.
Время вычисления у меня на машине - меньше 1 с.
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
#include <time.h>
#include <stdio.h>
#include <malloc.h>
#include <math.h>
 
long B=10000; 
long LB=4;    
long MaxDiv=450;  
 
void SetToInteger (long n, long *x, long Integer) {
  long i;
  for (i=1; i<n; i++) x[i] = 0;
  x[0] = Integer;
}
 
long IsZero (long n, long *x) {
  long i;
  for (i=0; i<n; i++)  
    if (x[i])   return 0;
        return 1;
}
 
void Add (long n, long *x, long *y) {
  long carry=0, i;
  for (i=n-1; i>=0; i--) {
    x[i] += y[i]+carry;
    if (x[i]<B) carry = 0;
    else {
      carry = 1;
      x[i] -= B;
    }
  }  
}
 
void Sub (long n, long *x, long *y) {
  long i;
  for (i=n-1; i>=0; i--) {
    x[i] -= y[i];
                if (x[i]<0) {
                  if (i) {      
        x[i] += B;
        x[i-1]--;
      }
                }
  }  
}
 
void Mul (long n, long *x, long q) {
  long carry=0, xi, i;
  for (i=n-1; i>=0; i--) {
    xi  = x[i]*q;               
    xi += carry;                
    if (xi>=B) {
      carry = xi/B;
      xi -= (carry*B);
    }
    else 
      carry = 0;
    x[i] = xi;
        }  
}
 
void Div (long n, long *x, long d, long *y) {
  long carry=0, xi, q, i;
  for (i=0; i<n; i++) {
    xi    = x[i]+carry*B;
    q     = xi/d;
    carry = xi-q*d;   
    y[i]  = q;        
  }  
}
 
void arccot (long p, long n, long *x, long *buf1, long *buf2) {
  long p2=p*p, k=3, sign=0;
  long *uk=buf1, *vk=buf2;
  SetToInteger (n, x, 0);
  SetToInteger (n, uk, 1);      /* uk = 1/p */
  Div (n, uk, p, uk);
  Add (n, x, uk);               /* x  = uk */
 
  while (!IsZero(n, uk)) {
    if (p<MaxDiv)
      Div (n, uk, p2, uk);  /* Первый шаг уменьшает p */
    else {
      Div (n, uk, p, uk);   /* Второй увеличивает p */
      Div (n, uk, p, uk);  
    }
    /* uk = u(k-1)/(p^2) */
    Div (n, uk, k, vk);       /* vk = uk/k  */
    if (sign) Add (n, x, vk); /* x = x+vk   */
    else Sub (n, x, vk);      /* x = x-vk   */
    k+=2;
    sign = 1-sign;
  }
}
 
void Print (long n, long *x) {
  long i; 
  printf ("%d.", x[0]);
  for (i=1; i<n; i++) {
    printf ("%.4d", x[i]);
    if (i%25==0) printf ("%8d\n", i*4);
  }
  printf ("\n");
}
 
void main () {  
  clock_t endclock, startclock; 
  long NbDigits=10000, NbArctan;
  long p[10], m[10];
  long size=1+NbDigits/LB, i;
  long *Pi      = (long *)malloc(size*sizeof(long));
  long *arctan  = (long *)malloc(size*sizeof(long));
  long *buffer1 = (long *)malloc(size*sizeof(long));
  long *buffer2 = (long *)malloc(size*sizeof(long)); 
  startclock = clock();    
  /*
  ** Используем: 
  ** Pi/4 = 12*arctan(1/18)+8*arctan(1/57)-5*arctan(1/239) (Гаусс)  
  **   
  */
  NbArctan = 3;
  m[0] = 12; m[1] = 8;  m[2] = -5;
  p[0] = 18; p[1] = 57; p[2] = 239; 
  SetToInteger (size, Pi, 0);
  /*
  ** Вычисляем Pi/4 = Sum(i) [m[i]*arctan(1/p[i])] 
  */
  for (i=0; i<NbArctan; i++) {
    arccot (p[i], size, arctan, buffer1, buffer2);
    Mul (size, arctan, abs(m[i]));
    if (m[i]>0) Add (size, Pi, arctan);  
    else        Sub (size, Pi, arctan);  
  }
  Mul (size, Pi, 4);
  endclock = clock ();
  Print (size, Pi);  /* Печатаем Pi */
  printf ("Time is : %9.2f seconds\n",  
         (float)(endclock-startclock)/(float)CLOCKS_PER_SEC ); 
  free (Pi);
  free (arctan);
        free (buffer1);
        free (buffer2);
}
easybudda
Эксперт С++
9456 / 5469 / 927
Регистрация: 25.07.2009
Сообщений: 10,495
07.08.2010, 00:37     Как просчитать число ПИ до определенного знака? #6
_nic, а чем Вас константа M_PI из math.h не устроила?
Код
$ grep PI /usr/include/math.h
#define M_PI            3.14159265358979323846
_nic
0 / 0 / 0
Регистрация: 04.05.2010
Сообщений: 112
07.08.2010, 11:14  [ТС]     Как просчитать число ПИ до определенного знака? #7
Помню была такая программа которая бенчила проц путем просчета пи,вот мне так и нада нагрузить процессор.Каким нибудь ресурсоемким мат. вычислением.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
07.08.2010, 16:28     Как просчитать число ПИ до определенного знака?
Еще ссылки по теме:
Определите в двумерном числовом массиве число соседства с двух чисел разного знака C++
C++ Преобразовать символьную запись целого десятичного числа без знака в целое число
C++ Каким образом можно вывести число без знака минус, если оно отрицательное?
Вывести на экран с точностью два знака число "е" (натуральный логарифм) C++
Просчитать минимальную дистанцию между человеком и станциями C++

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
outoftime
║XLR8║
506 / 428 / 33
Регистрация: 25.07.2009
Сообщений: 2,295
07.08.2010, 16:28     Как просчитать число ПИ до определенного знака? #8
_nic, Вот:
C++
1
2
3
4
5
6
7
8
#include <iostream>
#include <limits>
int main(){
    for(int i = numeric_limits<int>::min(); i < numeric_limits<int>::max();++i)
        for(int j = numeric_limits<int>::min(); j < numeric_limits<int>::max();++j)
            for(int k = numeric_limits<int>::min(); k < numeric_limits<int>::max();++k)
    return 0;
}
Обычный процессор, под win32 будет больше часа загружен на всю катушку

Добавлено через 9 минут
Не желательно проверять именно этот код, можно поставить цикл на 1000000 и посмотреть время выполнения, это будет где-то секунда, потом разделить (4294967295)^3 / 1000000 и получите время в секундах, которое ваш процессор точно не будет отдыхать

Добавлено через 1 час 34 минуты
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <limits>
#include <iomanip>
#include <ctime>
 
using namespace std;
 
typedef vector<int> VI;
typedef vector<VI> VVI;
typedef long long LL;
 
#define FOR(i,a,b) for (int i(a), _n(b); i < _n; ++i)
#define MIN(a,b) ( (a) < (b) ? a : b )
#define MAX(a,b) ( (a) > (b) ? a : b )
#define ALL(a) a.begin(), a.end()
 
const LL base = 1000*1000;
 
VI operator - (VI, VI);
VI operator -= (VI &, VI);
VI operator + (VI, VI);
VI operator * (const VI, VI);
VI operator * (VI, const int);
VI operator / (VI, const int);
ostream &operator << (ostream &, VI);
 
int main(){
    VI a(2); a[0] = 967295, a[1] = 4294;
 
    time_t begin = clock();
    FOR(i,0,1000*1000*1000) continue;
    time_t end = clock();
    int total_time = end - begin;
 
    VI miliseconds = a*a*a*total_time/(1000*1000*1000), // здесь все верно
       hours = miliseconds / (1000 * 60 * 60),
       minutes = (miliseconds - hours * (1000 * 60 * 60)) / (1000 * 60),
       seconds = (miliseconds - hours * (1000 * 60 * 60) - minutes * (1000 * 60)) / 1000;
    miliseconds -= hours * (1000 * 60 * 60) + minutes * (1000 * 60) + seconds * 1000;
 
    cout << "Time of following code:\n"
            "for(int i = numeric_limits<int>::min(); i < numeric_limits<int>::max();++i)\n\t"
            "for(int j = numeric_limits<int>::min(); j < numeric_limits<int>::max();++j)\n\t\t"
            "for(int k = numeric_limits<int>::min(); k < numeric_limits<int>::max();++k))\n";
    cout << "Is: [" << hours << "] hours [" << minutes << "] minuts [" << seconds << 
        "] seconds [" << miliseconds << "] miliseconds\n";
    return 0;
}
 
VI operator - (VI a, VI b){
    for (int i = 0, carry = 0; i < b.size() || carry; ++i){
        a[i] -= carry + (i < b.size() ? b[i] : 0);
        carry = a[i] < 0;
        carry ? a[i] += base : 0;       
    }
    while (!a.back() && a.size() > 1) a.pop_back();
    return a;
}
 
VI operator -= (VI &a, VI b){
    a = a - b;
    return a;
}
 
VI operator + (VI a, VI b){
    for (int i = 0, carry = 0; i < MAX(a.size(),b.size()) || carry; ++i){
        if (i == a.size()) a.push_back(0);
        a[i] += carry + (i < b.size() ? b[i] : 0);
        carry = a[i] >= base;
        carry ? a[i] -= base : 0;
    }
    while (!a.back() && a.size() > 1) a.pop_back();
    return a;
}
 
VI operator * (const VI a, VI b){
    VI res(a.size() + b.size(), 0);
    for (int i = 0, carry = 0; i < a.size(); ++i){
        for (int j = 0; j < b.size() || carry; ++j){
            if (j == b.size()) b.push_back(0);
            LL cur = a[i]*1ll*b[j] + carry + res[i+j];
            res[i+j] += cur % base;
            carry = cur / base;
        }
    }
    while (!res.back() && res.size() > 1) res.pop_back();
    return res;
}
 
VI operator * (VI a, const int b){
    for (int i = 0, carry = 0; i < a.size() || carry; ++i){
        if (i == a.size()) a.push_back(0);
        LL cur = a[i] * 1ll * b + carry;
        a[i] = cur % base;
        carry = cur / base;
    }
    while (!a.back() && a.size() > 1) a.pop_back();
    return a;
}
 
VI operator / (VI a, const int b){
    for (int i = a.size()-1, carry = 0; i > -1; --i){
        LL cur = a[i] + carry*1ll*base;
        a[i] = cur / b;
        carry = cur % b;
    }
    while(!a.back() && a.size() > 1) a.pop_back();
    return a;
}
 
ostream &operator << (ostream &out, VI a){
    out << (a.empty() ? 0 : a.back());
    for (int i = a.size()-2; i > -1; --i) out << setfill('0') << setw(6) << a[i];
    return out;
}
Эта программа за 3 секунды вам покажет время выполнение вышеприведенного кода.

Добавлено через 18 минут
Касательно вычисления числа Пи, то метода быстрее за формулу Джона Мэчина я не видел. Ее вы можете посмотреть в вики по ссылке, что дал Хохол. И даже не пытайтесь находить число Пи в даблах - очень низкая точность, лучше пишите длинную арифметику на дробных числах, или используйте cmath.
Yandex
Объявления
07.08.2010, 16:28     Как просчитать число ПИ до определенного знака?
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru