С Новым годом! Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
0 / 0 / 0
Регистрация: 10.02.2019
Сообщений: 1

Вычисление N-го знака числа Пи без вычисления предыдущих

10.02.2019, 14:23. Показов 4495. Ответов 0
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Всем доброго времени суток!
Недавно препод дал нам задание которое выглядит таким образом:
"Написание программы вычисления 30 тысячного знака после запятой числа пи".
Попробовал выполнить с помощью рядов Тейлора, формулой Валиса(формул оказалось великое множество вики) но походу до 30-тысячного знака таким образом никак не добраться.
И тут нашел статью на хабре с формулой где можно вычислить N-ый знак без нахождения предыдущих + готовый код на С. Но я не понимаю как работает алгоритм вычисления.

Как же работает алгоритм вычисления N-го знака Пи?
К примеру, если нам нужен 1000-й шестнадцатеричный знак числа Пи, мы домножаем всю формулу на 16^1000, тем самым обращая множитель, стоящий перед скобками, в 16^(1000-k). При возведении в степень мы используем двоичный алгоритм возведения в степень или, как будет показано в примере ниже, возведение в степень по модулю. После этого вычисляем сумму нескольких членов ряда. Причём необязательно вычислять много: по мере возрастания k 16^(N-k) быстро убывает, так что, последующие члены не будут оказывать влияния на значение искомых цифр). Вот и вся магия — гениальная и простая.

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
/*  
    This program implements the BBP algorithm to generate a few hexadecimal
    digits beginning immediately after a given position id, or in other words
    beginning at position id + 1.  On most systems using IEEE 64-bit floating-
    point arithmetic, this code works correctly so long as d is less than
    approximately 1.18 x 10^7.  If 80-bit arithmetic can be employed, this limit
    is significantly higher.  Whatever arithmetic is used, results for a given
    position id can be checked by repeating with id-1 or id+1, and verifying 
    that the hex digits perfectly overlap with an offset of one, except possibly
    for a few trailing digits.  The resulting fractions are typically accurate 
    to at least 11 decimal digits, and to at least 9 hex digits.  
*/
 
/*  David H. Bailey     2006-09-08 */
 
#include <stdio.h>
#include <math.h>
 
int main()
{
  double pid, s1, s2, s3, s4;
  double series (int m, int n);
  void ihex (double x, int m, char c[]);
  int id = 1000000;
#define NHX 16
  char chx[NHX];
 
/*  id is the digit position.  Digits generated follow immediately after id. */
 
  s1 = series (1, id);
  s2 = series (4, id);
  s3 = series (5, id);
  s4 = series (6, id);
  pid = 4. * s1 - 2. * s2 - s3 - s4;
  pid = pid - (int) pid + 1.;
  ihex (pid, NHX, chx);
  printf (" position = %i\n fraction = %.15f \n hex digits =  %10.10s\n",
  id, pid, chx);
}
 
void ihex (double x, int nhx, char chx[])
 
/*  This returns, in chx, the first nhx hex digits of the fraction of x. */
 
{
  int i;
  double y;
  char hx[] = "0123456789ABCDEF";
 
  y = fabs (x);
 
  for (i = 0; i < nhx; i++){
    y = 16. * (y - floor (y));
    chx[i] = hx[(int) y];
  }
}
 
double series (int m, int id)
 
/*  This routine evaluates the series  sum_k 16^(id-k)/(8*k+m) 
    using the modular exponentiation technique. */
 
{
  int k;
  double ak, eps, p, s, t;
  double expm (double x, double y);
#define eps 1e-17
 
  s = 0.;
 
/*  Sum the series up to id. */
 
  for (k = 0; k < id; k++){
    ak = 8 * k + m;
    p = id - k;
    t = expm (p, ak);
    s = s + t / ak;
    s = s - (int) s;
  }
 
/*  Compute a few terms where k >= id. */
 
  for (k = id; k <= id + 100; k++){
    ak = 8 * k + m;
    t = pow (16., (double) (id - k)) / ak;
    if (t < eps) break;
    s = s + t;
    s = s - (int) s;
  }
  return s;
}
 
double expm (double p, double ak)
 
/*  expm = 16^p mod ak.  This routine uses the left-to-right binary 
    exponentiation scheme. */
 
{
  int i, j;
  double p1, pt, r;
#define ntp 25
  static double tp[ntp];
  static int tp1 = 0;
 
/*  If this is the first call to expm, fill the power of two table tp. */
 
  if (tp1 == 0) {
    tp1 = 1;
    tp[0] = 1.;
 
    for (i = 1; i < ntp; i++) tp[i] = 2. * tp[i-1];
  }
 
  if (ak == 1.) return 0.;
 
/*  Find the greatest power of two less than or equal to p. */
 
  for (i = 0; i < ntp; i++) if (tp[i] > p) break;
 
  pt = tp[i-1];
  p1 = p;
  r = 1.;
 
/*  Perform binary exponentiation algorithm modulo ak. */
 
  for (j = 1; j <= i; j++){
    if (p1 >= pt){
      r = 16. * r;
      r = r - (int) (r / ak) * ak;
      p1 = p1 - pt;
    }
    pt = 0.5 * pt;
    if (pt >= 1.){
      r = r * r;
      r = r - (int) (r / ak) * ak;
    }
  }
 
  return r;
}
Как перевести полученное значение при выводе программы в десятичное(при переводе выдает длинную последовательность цифр).

Если кто понял как это работает пожалуйста добавьте внятные комментарий к коду или объясните на словах. Спасибо заранее!
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
10.02.2019, 14:23
Ответы с готовыми решениями:

Вычисление N-го знака числа Пи без вычисления предыдущих
Учусь программированию и стоит задачка найти число пи Nго знака. Наткнулся на формулу https://habr.com/ru/post/179829/ (см. рис.) и сразу...

Определить цифры целого числа (тип числа - целое без знака)
Определить цифры целого числа( тип числа-целое без знака), вычислить сумму полученных цифр. Помогите ,пожалуйста.

Написать функцию вычисления знака числа
Здравствуйте! Прошу прощения за глупый вопрос, мог бы спросить и у препода, но ждать долго, а сдать хочу досрочно) Задание прикрепил ниже. ...

0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
10.02.2019, 14:23
Помогаю со студенческими работами здесь

Вывод числа без знака '-'
Доброго времени суток. У ввожу число положительное или отрицательное, когда я ложу отрицательное число, то после вычислений я его должен...

Найти сумму цифр целого числа без учёта знака
Найти сумму цифр целого числа (без учета знака) (12345-&gt;15)

RegEx: Поиск числа и его получение без разделительного знака
есть текст например: &quot;бла бла 1.34 бла ла бла &quot; нужно вытащить 134 без точки. дошел до: (@&quot;(?&lt;=бла )\d+&quot;) но не...

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

Программа перевода целого числа без знака в двоичную систему счисления
Здравствуйте . Помогите , пожалуйста , реализовать программу перевода целого числа без знака в двоичную систему счисления , при этом выдать...


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

Или воспользуйтесь поиском по форуму:
1
Ответ Создать тему
Новые блоги и статьи
Модель микоризы: классовый агентный подход
anaschu 02.01.2026
Раньше это было два гриба и бактерия. Теперь три гриба, растение. И на уровне агентов добавится между грибами или бактериями взаимодействий. До того я пробовал подход через многомерные массивы,. . .
Учёным и волонтёрам проекта «Einstein@home» удалось обнаружить четыре гамма-лучевых пульсара в джете Млечного Пути
Programma_Boinc 01.01.2026
Учёным и волонтёрам проекта «Einstein@home» удалось обнаружить четыре гамма-лучевых пульсара в джете Млечного Пути Сочетание глобально распределённой вычислительной мощности и инновационных. . .
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост.
Programma_Boinc 28.12.2025
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост. Налог на собак: https:/ / **********/ gallery/ V06K53e Финансовый отчет в Excel: https:/ / **********/ gallery/ bKBkQFf Пост отсюда. . .
Кто-нибудь знает, где можно бесплатно получить настольный компьютер или ноутбук? США.
Programma_Boinc 26.12.2025
Нашел на реддите интересную статью под названием Anyone know where to get a free Desktop or Laptop? Ниже её машинный перевод. После долгих разбирательств я наконец-то вернула себе. . .
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка.
Programma_Boinc 23.12.2025
Рецензия / Мнение/ Перевод Нашел на реддите интересную статью под названием The Thinkpad X220 Tablet is the best budget school laptop period . Ниже её машинный перевод. Thinkpad X220 Tablet —. . .
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru