powered by simpleCommunicator - 2.0.53     © 2025 Programmizd 02
Форумы / Visual Basic [игнор отключен] [закрыт для гостей] / Число ПИ
25 сообщений из 88, страница 2 из 4
Число ПИ
    #38517823
Фотография VladConn
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Volodbka,

Здесь у тебя проблема:

Код: vbnet
1.
2.
3.
For i% = 0 To nhx - 1
'y = 16$ * (y - Floor(y))
End Function
...
Рейтинг: 0 / 0
Число ПИ
    #38517824
Фотография VladConn
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
И нотация с %, $ и т.п. уже наверно лет десять как не используется...
...
Рейтинг: 0 / 0
Число ПИ
    #38517828
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
VladConnИ нотация с %, $ и т.п. уже наверно лет десять как не используется...не используется - ведь не значит, что не поддерживается, пусть делает так, если хочет
...
Рейтинг: 0 / 0
Число ПИ
    #38517845
Volodbka
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Shocker.Pro,

я спутал решетки с долларами и хотел показать на примере что они работают
...
Рейтинг: 0 / 0
Число ПИ
    #38517848
Volodbka
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
VladConn,

я пытаюсь разобраться с функцией expm (), это видимо какой-то алгоритм быстрого возведения в степень, причем слева на право, как с ним разберусь, буду смотреть другие функции.
Предполагаю запускать каждую функцию в excel по отдельности, а потом постараюсь воссоединить их в целое по смыслу.
...
Рейтинг: 0 / 0
Число ПИ
    #38517853
Volodbka
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Предлагаю посмотреть вот эту функцию, пока она не работает

Код: vbnet
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.
Option Explicit

    Public Function expm(ByVal p As Double, ByVal ak As Double)
    'expm = 16 ^ р мод ak. Эта процедура использует бинарную схему
    'возведения в степень слева-направо.

    Dim i As Integer
    Dim j As Integer
    Dim p1 As Double
    Dim pt As Double
    Dim r As Double
    Dim ntp As Integer
    
    Static tp(25) As Double
    Static tp1 As Integer
    
    tp1% = 0
    ntp% = 25
    
    'Если это первый вызов expm, то заполнить массив tp.
    If tp1 = 0 Then
        tp1 = 1
        tp(0) = 1

            For i = 1 To ntp Step 1
            tp(i) = 2 * tp(i - 1)
            Next i
    End If

    If ak = 1 Then expm = 0

    'Найти наибольшую степень двойки меньше или равной р.
    For i = 0 To ntp Step 1
        If tp(i) > p Then Exit For
            pt = tp(i - 1)
            p1 = p
            r = 1
    Next i%

    'Выполните бинарный алгоритм возведения в степень по модулю ак.
    For j% = 1 To i% Step 1
        If p1 >= pt Then
            r = 16 * r
            r = r - Int((r / ak) * ak)
            p1 = p1 - pt
        End If
 
    pt = 0.5 * pt
  
        If pt >= 1 Then
            r = r * r
            r = r - Int((r / ak) * ak)
        End If
    Next j

    expm = r

End Function
...
Рейтинг: 0 / 0
Число ПИ
    #38517863
Volodbka
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Для сравнения исходный код в C++
Код: plaintext
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.
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 / 0
Число ПИ
    #38517865
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
очевидно, неправильно адаптирован фрагмент
Код: plaintext
1.
2.
3.
4.
5.
  for (i = 0; i < ntp; i++) if (tp[i] > p) break;

  pt = tp[i-1];
  p1 = p;
  r = 1.;

три последние оператора в оригинале в цикл не входят, а у тебя входят.

да, объявление static там не зря - иначе комментарий "'Если это первый вызов expm, то заполнить массив tp." бессмысленнен - вызов всегда будет считаться первым
...
Рейтинг: 0 / 0
Число ПИ
    #38517872
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Да, и еще, если я ничего не путаю, конструкция
Код: plaintext
1.
for (i = 0; i < ntp; i++)

проходит цикл от 0 до ntp-1, а у тебя цикл идет от 0 до ntp
...
Рейтинг: 0 / 0
Число ПИ
    #38517891
Фотография VladConn
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Volodbka,

Если ты отдекларировал переменную таким образом:
Код: vbnet
1.
Static tp1 As Integer

, то нет нужды в записи
Код: vbnet
1.
tp1% = 0

. Достаточно
Код: vbnet
1.
tp1 = 0

. Это касается всех переменных.
...
Рейтинг: 0 / 0
Число ПИ
    #38517989
Фотография VladConn
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Volodbka,

Мне кажется, что это условие будет исполняться всегда....

:)

Код: vbnet
1.
2.
3.
4.
5.
    tp1% = 0
    ntp% = 25
    
    'Если это первый вызов expm, то заполнить массив tp.
    If tp1 = 0 Then
...
Рейтинг: 0 / 0
Число ПИ
    #38517991
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
VladConnМне кажется, что это условие будет исполняться всегда....ну да, надо ее объявить как static, а инициализацию убрать.
...
Рейтинг: 0 / 0
Число ПИ
    #38517992
Фотография VladConn
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Volodbka,

Мне кажется, что в исходном коде эта строка:
Код: plaintext
1.
static int tp1 = 0;


скорее всего эквивалентна этой строке на VB:
Код: vbnet
1.
Static tp1 As Integer


Поэтому существование этой строки в твоем коде
Код: vbnet
1.
tp1% = 0


а) Излишне
б) Разрушительно
...
Рейтинг: 0 / 0
Число ПИ
    #38518076
Volodbka
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
VolodbkaДля сравнения исходный код в C++
Код: plaintext
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.
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;
}



Код: vbnet
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.
Option Explicit

    Public Function expm(ByVal p As Double, ByVal ak As Double)
    'expm = 16 ^ р мод ak. Эта процедура использует бинарную схему
    'возведения в степень слева-направо.

    Dim i As Integer
    Dim j As Integer
    Dim p1 As Double
    Dim pt As Double
    Dim r As Double
    Dim ntp As Integer
    
    Static tp(25) As Double
    Static tp1 As Integer
    
    ntp = 25
    
    'Если это первый вызов expm, то заполнить массив tp.
    If tp1 <> 1 Then
        tp1 = 1
        tp(0) = 1

            For i = 1 To ntp - 1 Step 1
            tp(i) = 2 * tp(i - 1)
            Next i
    End If

    If ak = 1 Then expm = 0

    'Найти наибольшую степень двойки меньше или равной р.
        For i = 0 To ntp - 1 Step 1
            If tp(i) > p Then Exit For
        Next i
            
            pt = tp(i - 1)
            p1 = p
            r = 1
    
    'Выполняет бинарный алгоритм возведения в степень по модулю ак.
    For j = 1 To i - 1 Step 1
        If p1 >= pt Then
            r = 16 * r
            r = r - Int((r / ak) * ak)
            p1 = p1 - pt
        End If
 
    pt = 0.5 * pt
  
        If pt >= 1 Then
            r = r * r
            r = r - Int((r / ak) * ak)
        End If
    Next j

    expm = r

End Function
...
Рейтинг: 0 / 0
Число ПИ
    #38518083
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Volodbka,

ты хоть пиши пояснение какое-то, а то код опубликовал, а дальше-то что? работает? ошибку выдает? неправильно считает?
...
Рейтинг: 0 / 0
Число ПИ
    #38518093
Volodbka
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Пока вот это

Было в С++
Код: plaintext
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.
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;
}



стало в VBA
Код: vbnet
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.
 Function series(m As Integer, id As Integer)
    'Эта процедура оценивает серию sum_k 16 ^ (ID-K) / (8 * K + M)
    'используя модульную технику возведения в степень.
    Dim k As Integer
    Dim ak As Double
    Dim eps As Double
    Dim p As Double
    Dim s As Double
    Dim t As Double
    Dim expm(x, y) As Double
    Dim eps
 
    eps = 1E-17
    s = 0

    'Суммирует ряд до идентификатора
 
    For k = 0 To id Step 1
        ak = 8 * k + m
        p = id - k
        t = expm(p, ak)
        s = s + t / ak
        s = s - Int(s)
    Next k%

    'Вычисляет несколько терминов, где к> = ID.

    For k = id To id + 100 Step 1
            ak = 8 * k + m
            
           't = pow (16., (double) (id - k)) / ak;
            t = 16 * (id - k) / ak
            
        If t < eps Then Exit For
        
            s = s + t
            s = s - Int(s)
    Next k
 
    series = s

    End Function
...
Рейтинг: 0 / 0
Число ПИ
    #38518097
Volodbka
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Функция expm() что-то считает, её в сторону, надо следующую функцию лепить series()

В series() непонятно: t = pow (16., (double) (id - k)) / ak
...
Рейтинг: 0 / 0
Число ПИ
    #38518103
Volodbka
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
pow - это возведение в степень, тут просто - "^" надо поставить,
а вот с этим как быть #define eps 1e-17?
...
Рейтинг: 0 / 0
Число ПИ
    #38518105
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
если не ошибаюсь
Const eps As Double = 1E-17
...
Рейтинг: 0 / 0
Число ПИ
    #38518110
Volodbka
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Так подправил, форы, степень.

Код: vbnet
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.
    Function series(m As Integer, id As Integer)
    'Эта процедура оценивает серию sum_k 16 ^ (ID-K) / (8 * K + M)
    'используя модульную технику возведения в степень.
    Dim k As Integer
    Dim ak As Double
    Dim eps As Double
    Dim p As Double
    Dim s As Double
    Dim t As Double
    Dim expm(x, y) As Double
    Const eps As Double = 1E-17

    s = 0

    'Суммирует ряд до идентификатора
 
    For k = 0 To id - 1 Step 1
        ak = 8 * k + m
        p = id - k
        t = expm(p, ak)
        s = s + t / ak
        s = s - Int(s)
    Next k%

    'Вычисляет несколько терминов, где к> = ID.

    For k = id To id - 1 + 100 Step 1
            ak = 8 * k + m
            
           't = pow (16., (double) (id - k)) / ak;
            t = 16 ^ ((id - k)) / ak
            
        If t < eps Then Exit For
        
            s = s + t
            s = s - Int(s)
    Next k
 
    series = s

    End Function
...
Рейтинг: 0 / 0
Число ПИ
    #38518118
Volodbka
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Пока вот! Функция series тоже что-то считает, осталось еще две функции там будет жарко

Код: vbnet
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.
Option Explicit

Public Const eps As Double = 1E-17

    Function series(m As Integer, id As Integer)
    'Эта процедура оценивает серию sum_k 16 ^ (ID-K) / (8 * K + M)
    'используя модульную технику возведения в степень.
    Dim k As Integer
    Dim ak As Double
    Dim eps As Double
    Dim p As Double
    Dim s As Double
    Dim t As Double
    
    s = 0

    'Суммирует ряд до идентификатора
 
    For k = 0 To id - 1 Step 1
        ak = 8 * k + m
        p = id - k
        t = expm(p, ak)
        s = s + t / ak
        s = s - Int(s)
    Next k%

    'Вычисляет несколько терминов, где к> = ID.

    For k = id To id - 1 + 100 Step 1
            ak = 8 * k + m
            
           't = pow (16., (double) (id - k)) / ak;
            t = 16 ^ ((id - k)) / ak
            
        If t < eps Then Exit For
        
            s = s + t
            s = s - Int(s)
    Next k
 
    series = s

    End Function


    Public Function expm(ByVal p As Double, ByVal ak As Double)
    'expm = 16 ^ р мод ak. Эта процедура использует бинарную схему
    'возведения в степень слева-направо.

    Dim i As Integer
    Dim j As Integer
    Dim p1 As Double
    Dim pt As Double
    Dim r As Double
    Dim ntp As Integer
    
    Static tp(25) As Double
    Static tp1 As Integer
    
    ntp = 25
    
    'Если это первый вызов expm, то заполнить массив tp.
    If tp1 <> 1 Then
        tp1 = 1
        tp(0) = 1

            For i = 1 To ntp - 1 Step 1
            tp(i) = 2 * tp(i - 1)
            Next i
    End If

    If ak = 1 Then expm = 0

    'Найти наибольшую степень двойки меньше или равной р.
        For i = 0 To ntp - 1 Step 1
            If tp(i) > p Then Exit For
        Next i
            
            pt = tp(i - 1)
            p1 = p
            r = 1
    
    'Выполняет бинарный алгоритм возведения в степень по модулю ак.
    For j = 1 To i - 1 Step 1
        If p1 >= pt Then
            r = 16 * r
            r = r - Int((r / ak) * ak)
            p1 = p1 - pt
        End If
 
    pt = 0.5 * pt
  
        If pt >= 1 Then
            r = r * r
            r = r - Int((r / ak) * ak)
        End If
    Next j

    expm = r

End Function
...
Рейтинг: 0 / 0
Число ПИ
    #38518129
Volodbka
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вот следующий кролик
Было в С++

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
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];
  }
}



Стало в VBA

Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
  Function ihex(x As Double, nhx As Integer, ByRef chx As String)
    Dim i As Integer
    Dim y As Double
    Dim hx As Double
        hx = "0123456789ABCDEF"
    
        y = Abs(x)
    
    For i = 0 To nhx - 1
        'y = 16# * (y - Floor(y))
        'chx(i) = hx(int( y))
    Next nhx
    
    End Function
...
Рейтинг: 0 / 0
Число ПИ
    #38518130
Фотография VladConn
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Volodbka,

Если получится, ты будешь первый, кто опубликует алгоритм BBP для числа пи, исполненный на VB.
...
Рейтинг: 0 / 0
Число ПИ
    #38518132
Фотография VladConn
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Только зачем присваивать строку числовой переменной...
...
Рейтинг: 0 / 0
Число ПИ
    #38518141
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Следует переписать
Код: plaintext
1.
char hx[] = "0123456789ABCDEF";


как
Код: vbnet
1.
2.
Dim hx() As String * 1
hx = Array("0", "1", "2"....)
...
Рейтинг: 0 / 0
25 сообщений из 88, страница 2 из 4
Форумы / Visual Basic [игнор отключен] [закрыт для гостей] / Число ПИ
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]