powered by simpleCommunicator - 2.0.53     © 2025 Programmizd 02
Форумы / Visual Basic [игнор отключен] [закрыт для гостей] / Число ПИ
25 сообщений из 88, страница 3 из 4
Число ПИ
    #38518155
Volodbka
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Было в C++
Код: 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.
15.
16.
17.
18.
   Function ihex(x As Double, nhx As Integer, ByRef chx As String)
    
    'Возвращает, в СНХ, первые NHX шестигранные цифры фракции х.
    
    Dim i As Integer
    Dim y As Double
    Dim hx As Double
        
        hx = Array("0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F")
    
        y = Abs(x)
    
    For i = 0 To nhx - 1
        y = 16 * (y - Int(y))
        chx(i) = hx(Int(y))
    Next nhx
    
    End Function
...
Рейтинг: 0 / 0
Число ПИ
    #38518157
Volodbka
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
что-то мне подсказывает что здесь всегда будет 0, y = 16 * (y - Int(y))
...
Рейтинг: 0 / 0
Число ПИ
    #38518160
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Volodbka,

Почему?

Единственное, не помешало бы 16 сделать Double, а то все выражение может превратиться в целое

Шестигранные цифры!
...
Рейтинг: 0 / 0
Число ПИ
    #38518162
Volodbka
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
VladConnТолько зачем присваивать строку числовой переменной...
А в исходном С++ вроде меняется
...
Рейтинг: 0 / 0
Число ПИ
    #38518179
Фотография VladConn
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
VolodbkaVladConnТолько зачем присваивать строку числовой переменной...
А в исходном С++ вроде меняется

В исходнике такого присваивания нет.
...
Рейтинг: 0 / 0
Число ПИ
    #38518180
Фотография VladConn
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Volodbkaчто-то мне подсказывает что здесь всегда будет 0, y = 16 * (y - Int(y))

Здесь "y" всегда double, a Int(y) всегда integer. Разница между ними этого не позволит.
...
Рейтинг: 0 / 0
Число ПИ
    #38518185
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: sql
1.
2.
3.
4.
Dim y As Double
y = 3.45
y = 16 * (y - Int(y))
Debug.Print y



результат 7.2
...
Рейтинг: 0 / 0
Число ПИ
    #38518187
Volodbka
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
VladConn,
ок, а какой тип присвоить chx - integer?
...
Рейтинг: 0 / 0
Число ПИ
    #38518188
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
VladConna Int(y) всегда integerк тому же, ты не прав:
Код: vbnet
1.
2.
?typename(int(4.56))
Double
...
Рейтинг: 0 / 0
Число ПИ
    #38518189
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
VolodbkaVladConn,
ок, а какой тип присвоить chx - integer?зачем?? там же строка
...
Рейтинг: 0 / 0
Число ПИ
    #38518192
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Volodbka, VladConn

Вы друг друга не поняли и говорите про разные переменные
VladConn про hx, а Volodbka про chx
...
Рейтинг: 0 / 0
Число ПИ
    #38518198
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.
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.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
Option Explicit

Public Const eps As Double = 1E-17
Public Const NHX  As Double = 16

' Эта программа реализует алгоритм BBP генерировать несколько
' шестнадцатеричных цифр, начиная сразу после заданной позиции ID,
' или, другими словами, начиная с позиции ID + 1. На большинстве систем,
' использующих 64-разрядную арифметику IEEE с плавающей запятой,
' этот код работает правильно, пока г меньше примерно 1,18 х 10 ^ 7.
' Если 80-битный арифметическое могут быть использованы,
' этот предел значительно выше. Независимо арифметика используется,
' результаты для данной позиции ID можно проверить путем повторения с ID-1 или ID 1,
' и проверки, что шестнадцатеричные цифры прекрасно перекрывают со смещением одного,
' за исключением, возможно в течение нескольких хвостовых цифр. Полученные фракции,
' как правило, с точностью не менее 11 десятичных цифр, и, по крайней мере 9 шестнадцатеричных цифр.


    Private Function main() As Integer
    Dim pid As Double
    Dim s1 As Double
    Dim s2 As Double
    Dim s3 As Double
    Dim s4 As Double
    Dim series#(m%, n%)
    Dim id%
    'void ihex(x%, m%, char c())
    id% = 1000000
    '#define NHX 16
    ' char chx[NHX];
    'идентификатор цифры положения. Цифры генерируется следовать сразу после идентификатором.
    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# - pid# + 1#
    'ihex (pid, NHX, chx)
    'printf (" position = %i\n fraction = %.15f \n hex digits = %10.10s\n",id, pid, chx)

    End Function
  
    Public Function ihex(ByVal x As Double, ByVal NHX As Integer, ByRef chx)
    
    'Возвращает, в СНХ, первые NHX шестигранные цифры фракции х.
    
    Dim i As Integer
    Dim y As Double
    Dim hx
        
        hx = Array("0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F")
    
        y = Abs(x)
    
    For i = 0 To NHX - 1
        y = 16 * (y - Int(y))
        chx(i) = hx(Int(y))
    Next NHX
    
    End Function

    
    
    Public Function series(ByVal m As Integer, ByVal 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
Число ПИ
    #38518199
Фотография VladConn
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Shocker.ProVladConna Int(y) всегда integerк тому же, ты не прав:
Код: vbnet
1.
2.
?typename(int(4.56))
Double



Все равно возвращает integer, хоть и типа double (согласно Help).

авторBoth Int and Fix remove the fractional part of number and return the resulting integer value.
...
Рейтинг: 0 / 0
Число ПИ
    #38518202
Volodbka
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
кстати char встречается два раза в исходнике
...
Рейтинг: 0 / 0
Число ПИ
    #38518206
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
VladConnВсе равно возвращает integer, хоть и типа double (согласно Help).

авторBoth Int and Fix remove the fractional part of number and return the resulting integer value.
в данном случае слово integer означает не тип данных, а является частью фразы "...возвращает получившееся целое значение"
VolodbkaВот на размышлениеНад чем размышлять-то? Работает? нет?
...
Рейтинг: 0 / 0
Число ПИ
    #38518207
Фотография VladConn
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Shocker.Pro
VladConnВсе равно возвращает integer, хоть и типа double (согласно Help).

пропущено...
в данном случае слово integer означает не тип данных, а является частью фразы "...возвращает получившееся целое значение"
VolodbkaВот на размышлениеНад чем размышлять-то? Работает? нет?

А я про тип и не писал.
...
Рейтинг: 0 / 0
Число ПИ
    #38518339
Alibek B
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Shocker.ProСледует переписать
Зачем?
hx[i] -> Hex(i)
...
Рейтинг: 0 / 0
Число ПИ
    #38518341
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alibek B.Зачем?
hx[i] -> Hex(i)дельная мысль. Ну это уже из области оптимизации алгоритма, а не тупого перевода. Думаю, там можно еще что-нить подправить, если подумать.
...
Рейтинг: 0 / 0
Число ПИ
    #38518537
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.
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.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
170.
Option Explicit

Public Const eps As Double = 1E-17
Public Const NHX  As Double = 16

' Код программы помещают в модуль VBA Excel, печать результата производится на активный лист,
' подключение библиотек, форм и т.п. не требуется.

    Public Sub main()
    Dim i
    
    Dim pid As Double
    Dim s1 As Double
    Dim s2 As Double
    Dim s3 As Double
    Dim s4 As Double
    'Dim series#(m%, N%)
    Dim id 'as integer
    'void ihex(x%, m%, char c())
    id = 1000000
    '#define NHX 16
    ' char chx[NHX];
    'идентификатор цифры положения. Цифры генерируется следовать сразу после идентификатором.
    '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 - pid + 1
    'ihex (pid, NHX, chx)
    'printf (" position = %i\n fraction = %.15f \n hex digits = %10.10s\n",id, pid, chx)
    i = i + 1
    ActiveSheet.Cells(i, 1) = id 'выводит результат на активный лист
    ActiveSheet.Cells(i, 2) = pid
    ActiveSheet.Cells(i, 3) = "chx"
    End Sub
  
    Public Function ihex(ByVal x As Double, ByVal NHX As Integer, ByRef chx)
    
    'Возвращает, в СНХ, первые NHX шестигранные цифры фракции х.
    
    Dim i As Integer
    Dim y As Double
    Dim hx
        
        hx = Array("0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F")
    
        y = Abs(x)
    
    For i = 0 To NHX - 1
        y = 16 * (y - Int(y))
        chx(i) = hx(Int(y))
    Next NHX
    
    End Function

    
    
    Public Function series(ByVal m As Integer, ByVal id) '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



' Эта программа реализует алгоритм BBP генерировать несколько
' шестнадцатеричных цифр, начиная сразу после заданной позиции ID,
' или, другими словами, начиная с позиции ID + 1. На большинстве систем,
' использующих 64-разрядную арифметику IEEE с плавающей запятой,
' этот код работает правильно, пока г меньше примерно 1,18 х 10 ^ 7.
' Если 80-битный арифметическое могут быть использованы,
' этот предел значительно выше. Независимо арифметика используется,
' результаты для данной позиции ID можно проверить путем повторения с ID-1 или ID 1,
' и проверки, что шестнадцатеричные цифры прекрасно перекрывают со смещением одного,
' за исключением, возможно в течение нескольких хвостовых цифр. Полученные фракции,
' как правило, с точностью не менее 11 десятичных цифр, и, по крайней мере 9 шестнадцатеричных цифр.
...
Рейтинг: 0 / 0
Число ПИ
    #38518545
Volodbka
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
есть такая строчка в Sub Main()
printf (" position = %i\n fraction = %.15f \n hex digits = %10.10s\n",id, pid, chx)

правильно ли я понимаю что это вывод значений id, pid, chx. Непонятно что за переменная i в ней, пытаюсь реализовать вывод через cells на активный лист
...
Рейтинг: 0 / 0
Число ПИ
    #38518670
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Да, это вывод id, pid, chx
i - это не переменная
http://www.cplusplus.com/reference/cstdio/printf/
...
Рейтинг: 0 / 0
Число ПИ
    #38519151
Volodbka
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Привет, с Рождеством.

1 В общем я заменил тип Double на Variant, думаю на первых десяти итерациях счёта это замена не сильно повлияет на результат.
2 Завёл в блок main() цикл с переменной id.

Не могу разобраться в корреляциях между функциями.
Функция expm() подчинена функции series(), функция series() подчинена блоку main().

Проблема в завязке блока main() и функции ihex.

Зачем в функции ihex в связях прописана константа nhx, в моём понимание её наличие или отсутствие погоды не сделают, видимо это синтаксис С++? А может nhx вовсе и не константа, а переменная? Или днём константа, ночью переменная, многостоночница какая-та.

Опять в связях функции ihex сидит загадочная дама X, кто и как с ней работает для меня пока загадка.

В С++

Код: 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.
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;
}



в 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.
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.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
 Option Explicit
 
    Public Const eps As Variant = 1E-17
    Public Const NHX  As Integer = 16

' Код программы помещают в модуль VBA Excel, печать результата производится на активный лист,
' подключение библиотек, форм и т.п. не требуется.

    Public Sub main()
    
    Dim pid As Variant
    Dim s1 As Variant
    Dim s2 As Variant
    Dim s3 As Variant
    Dim s4 As Variant
    Dim id As Integer
    'void ihex(x%, m%, char c())
    
    For id = 1 To 1000 Step 1
    'id = 1000
    '#define NHX 16
    ' char chx[NHX];
    'идентификатор цифры положения. Цифры генерируется следовать сразу после идентификатором.
    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)

    ActiveSheet.Cells(Int(id), 1) = id 'выводит результат на активный лист
    ActiveSheet.Cells(Int(id), 2) = pid
   ' ActiveSheet.Cells(i, 3) = "chx"
    Next id
    
    End Sub
 
    Public Function ihex(ByVal x As Variant, ByVal NHX As Integer, ByVal chx)
    
    'Возвращает, в СНХ, первые NHX шестигранные цифры фракции х.
    
    Dim i As Integer
    Dim y As Variant
    Dim hx
              
        hx = Array("0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F")
    
        y = Abs(x)
    
    For i = 1 To NHX - 1
        y = 16 * (y - Int(y))
        chx(i) = hx(Int(y))
    Next i
    
    End Function
 
    Public Function series(ByVal m As Integer, ByVal id As Integer) 'id as integer
    'Эта процедура оценивает серию sum_k 16 ^ (ID-K) / (8 * K + M)
    'используя модульную технику возведения в степень.
    Dim k As Integer
    Dim ak As Variant
   
    Dim p As Variant
    Dim s As Variant
    Dim t As Variant
    
    s = 0

    'Суммирует ряд до идентификатора
 
    For k = 1 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 Variant, ByVal ak As Variant)
    'expm = 16 ^ р мод ak. Эта процедура использует бинарную схему
    'возведения в степень слева-направо.

    Dim i As Variant
    Dim j As Variant
    Dim p1 As Variant
    Dim pt As Variant
    Dim r As Variant
    Dim ntp As Variant
    
    Static tp(25) As Variant
    Static tp1 As Variant
    
    ntp = 25 '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 = 1 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
Число ПИ
    #38519156
Volodbka
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Это результат
...
Рейтинг: 0 / 0
Число ПИ
    #38519185
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Volodbka1 В общем я заменил тип Double на Variantа в чем глубокий смысл? Variant не есть тип сам по себе, переменная, которая хранится в Variant все равно имеет какой-то конкретный тип
Volodbka2 Завёл в блок main() цикл с переменной id.А это для чего? В оригинале никакого цикла нет, и id имеет значение 1000000
VolodbkaНе могу разобраться в корреляциях между функциями.
Функция expm() подчинена функции series(), функция series() подчинена блоку main().дополнительное объявление series в main по-моему надо просто проигнорировать
VolodbkaЗачем в функции ihex в связях прописана константа nhxгде? я такого не нашел
Volodbkaзагадочная дама X, кто и как с ней работает для меня пока загадка.а это? y = fabs (x);
...
Рейтинг: 0 / 0
Число ПИ
    #38519192
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Shocker.ProVolodbka1 В общем я заменил тип Double на Variantа в чем глубокий смысл? Variant не есть тип сам по себе, переменная, которая хранится в Variant все равно имеет какой-то конкретный типвот у тебя код
Код: vbnet
1.
2.
    Dim s As Variant
    s = 0

в этот момент s имеет тип Integer, как там дальше вычисления пойдут - фиг его знает и зачем об этом думать. Верни Double туда, где было double
...
Рейтинг: 0 / 0
25 сообщений из 88, страница 3 из 4
Форумы / Visual Basic [игнор отключен] [закрыт для гостей] / Число ПИ
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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