C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

C++からVBへの変換

[トピック内 26 記事 (1 - 20 表示)]  << 0 | 1 >>

■91843 / inTopicNo.1)  C++からVBへの変換
  
□投稿者/ えん (1回)-(2019/08/07(Wed) 12:25:40)

分類:[.NET 全般] 

以下のコードをVBに変換したいのですが、どうすれば良いですか?

for (m = n; (mq = m >> 2) >= 1; m = mq) {

}

C#→VBへの変換サイトは見つかるのですが
C++→VBの変換サイトってありますでしょうか?



引用返信 編集キー/
■91844 / inTopicNo.2)  Re[1]: C++からVBへの変換
□投稿者/ 774RR (717回)-(2019/08/07(Wed) 13:33:07)
元々のコードが極めて読みにくい時点で、そのままトランスレートしたって仕方ない感がひし形。
それでもあえて「そのまま」変換するなら

m = n
mq = m >> 2
Do While mq >= 1
   Console.WriteLine(mq)
   m = mq
   mq = m >> 2
Loop

超絶カッコ悪いので要修正かな

> C++→VBの変換サイトってありますでしょうか?
無いと断言する気はないけど、ほとんど全く不可能なので意味ないと思うっす。

引用返信 編集キー/
■91845 / inTopicNo.3)  Re[2]: C++からVBへの変換
□投稿者/ えん (2回)-(2019/08/07(Wed) 13:43:36)
ありがとうございます。

あと、これはどうなりますか?

i = 0;
for (j = 1; j < n - 1; j++) {
for (k = n >> 1; k > (i ^= k); k >>= 1);
}
}

^= がどういう処理をしているのか分からないのですが
引用返信 編集キー/
■91846 / inTopicNo.4)  Re[3]: C++からVBへの変換
□投稿者/ Hongliang (852回)-(2019/08/07(Wed) 13:57:21)
a ^= b

a = a ^ b
の省略記法。
演算子 ^ は排他的論理和を表し、VBでは演算子 Xor を使用します。
引用返信 編集キー/
■91848 / inTopicNo.5)  Re[4]: C++からVBへの変換
□投稿者/ えん (4回)-(2019/08/07(Wed) 14:28:48)
ありがとうございます。

実は
http://www.kurims.kyoto-u.ac.jp/~ooura/fftman/ftmn1_23.html#sec1_2_3

このページのコードを翻訳しています。



    theta = -8 * atan(1.0) / n;
    for (m = n; (mq = m >> 2) >= 1; m = mq) {
        for (i = 0; i < mq; i++) {
            w1r = cos(theta * i);
            w1i = sin(theta * i);
            w2r = cos(theta * 2 * i);
            w2i = sin(theta * 2 * i);
            w3r = cos(theta * 3 * i);
            w3i = sin(theta * 3 * i);
            for (j = i; j < n; j += m) {
                j1 = j + mq;
                j2 = j1 + mq;
                j3 = j2 + mq;
                x0r = ar[j] + ar[j2];
                x0i = ai[j] + ai[j2];
                x1r = ar[j] - ar[j2];
                x1i = ai[j] - ai[j2];
                x2r = ar[j1] + ar[j3];
                x2i = ai[j1] + ai[j3];
                x3r = ar[j3] - ar[j1];
                x3i = ai[j3] - ai[j1];
                ar[j] = x0r + x2r;
                ai[j] = x0i + x2i;
                x0r = x0r - x2r;
                x0i = x0i - x2i;
                ar[j1] = w2r * x0r - w2i * x0i;
                ai[j1] = w2r * x0i + w2i * x0r;
                x0r = x1r - x3i;
                x0i = x1i + x3r;
                ar[j2] = w1r * x0r - w1i * x0i;
                ai[j2] = w1r * x0i + w1i * x0r;
                x0r = x1r + x3i;
                x0i = x1i - x3r;
                ar[j3] = w3r * x0r - w3i * x0i;
                ai[j3] = w3r * x0i + w3i * x0r;
            }
        }
        theta *= 4;
    }

の部分は以下で合っていると思います。


        Dim theta = -Math.PI * 2 / n

        Dim m As Integer = n
        For g As Integer = 1 To CInt(Math.Log(n, 4))

            m = CInt(m / 4)          
            Dim mq As Integer = CInt(m / 4)

            For i As Integer = 0 To mq

                Dim w1r As Double = Math.Cos(theta * i)
                Dim w1i As Double = Math.Sin(theta * i)
                Dim w2r As Double = Math.Cos(theta * (2 * i))
                Dim w2i As Double = Math.Sin(theta * (2 * i))
                Dim w3r As Double = Math.Cos(theta * (3 * i))
                Dim w3i As Double = Math.Sin(theta * (3 * i))

                For j As Integer = i To n Step m

                    Dim j1 As Integer = j + mq
                    Dim j2 As Integer = j1 + mq
                    Dim j3 As Integer = j2 + mq
                    Dim x0r As Double = xr(j) + xr(j2)
                    Dim x0i As Double = xi(j) + xi(j2)
                    Dim x1r As Double = xr(j) - xr(j2)
                    Dim x1i As Double = xi(j) - xi(j2)
                    Dim x2r As Double = xr(j1) + xr(j3)
                    Dim x2i As Double = xi(j1) + xi(j3)
                    Dim x3r As Double = xr(j3) - xr(j1)
                    Dim x3i As Double = xi(j3) - xi(j1)
                    xr(j) = x0r + x2r
                    xi(j) = x0i + x2i
                    x0r = x0r - x2r
                    x0i = x0i - x2i
                    xr(j1) = (w2r * x0r) - (w2i * x0i)
                    xi(j1) = (w2r * x0i) + (w2i * x0r)
                    x0r = x1r - x3i
                    x0i = x1i + x3r
                    xr(j2) = (w1r * x0r) - (w1i * x0i)
                    xi(j2) = (w1r * x0i) + (w1i * x0r)
                    x0r = x1r + x3i
                    x0i = x1i - x3r
                    xr(j3) = (w3r * x0r) - (w3i * x0i)
                    xi(j3) = (w3r * x0i) + (w3i * x0r)

                Next j

            Next i

            theta *= 4

        Next g


しかし、
Dim x0r As Double = xr(j) + xr(j2)
のところで、
j2にj + mq + mqが代入されるため、
xrの要素数であるnを超えてしまい、エラーとなってしまいます。

一体どうすれば良いでしょうか?

もしかして、元のコードが間違っていますか?

引用返信 編集キー/
■91850 / inTopicNo.6)  Re[5]: C++からVBへの変換
□投稿者/ 魔界の仮面弁士 (2281回)-(2019/08/07(Wed) 16:02:00)
No91848 (えん さん) に返信
> theta = -8 * atan(1.0) / n;
>>
> Dim theta = -Math.PI * 2 / n

「Math.Atn(1.0) * 4」は「Math.PI」と同義なので、
ここは VB 側の書き方の方が分かりやすいですね。


> for (m = n; (mq = m >> 2) >= 1; m = mq) {
>>
> Dim m As Integer = n
> For g As Integer = 1 To CInt(Math.Log(n, 4))
>     m = CInt(m / 4)          
>     Dim mq As Integer = CInt(m / 4)

Visual Basic のバージョンは何ですか?

ビットシフト演算子を持たない VB7.0 (VB.NET 2002) の場合はさておき、
VB7.1 (VB.NET 2003) 以降であれば、元の処理そのまま
「>> 演算子」を使った方が移植しやすいかと思います。

未検証ですが、こんなイメージ?

Dim m As Integer = n
Dim mq As Integer = m >> 2
Do While mq >= 1
  '…
  '…
  '…
  m = mq
  mq = m >> 2 
Loop


> For g As Integer = 1 To CInt(Math.Log(n, 4))

CInt は切捨てでも四捨五入でも無いのでご注意を。

n が  2 の場合、CInt(Math.Log(n, 4)) は CInt(0.5000) となり、結果は 0 です。
n が  8 の場合、CInt(Math.Log(n, 4)) は CInt(1.5000) となり、結果は 2 です。
n が 32 の場合、CInt(Math.Log(n, 4)) は CInt(2.5000) となり、結果は 2 です。
n が128 の場合、CInt(Math.Log(n, 4)) は CInt(3.5000) となり、結果は 4 です。
n が512 の場合、CInt(Math.Log(n, 4)) は CInt(4.5000) となり、結果は 4 です。


>  m = CInt(m / 4)

上記は
 m \= 4
書けます。

引用返信 編集キー/
■91851 / inTopicNo.7)  Re[6]: C++からVBへの変換
□投稿者/ えん (5回)-(2019/08/07(Wed) 16:07:40)
ありがとうございます。

VBでもビットシフトを使えるのは分かりますが、
不慣れなせいかわかりづらいので、これを使わない方法に書き換えました。

nは常に4のべき乗ですので、
Math.Log(n, 4)の値は常に整数となります。


引用返信 編集キー/
■91852 / inTopicNo.8)  Re[7]: C++からVBへの変換
□投稿者/ えん (6回)-(2019/08/07(Wed) 16:10:01)
やはり、エラーが出ますが
どこが問題でしょうか?

引用返信 編集キー/
■91853 / inTopicNo.9)  Re[8]: C++からVBへの変換
□投稿者/ えん (8回)-(2019/08/07(Wed) 16:24:59)
すいません、自己解決しました

Forループの範囲で
>と>=を勘違いしていました

解決済み
引用返信 編集キー/
■91854 / inTopicNo.10)  (削除)
□投稿者/ -(2019/08/07(Wed) 16:38:16)
この記事は(投稿者)削除されました
引用返信 編集キー/
■91855 / inTopicNo.11)  Re[7]: C++からVBへの変換
□投稿者/ 魔界の仮面弁士 (2283回)-(2019/08/07(Wed) 16:48:10)
No91851 (えん さん) に返信
> VBでもビットシフトを使えるのは分かりますが、
> 不慣れなせいかわかりづらいので、これを使わない方法に書き換えました。

元の C++ コードを C# に置き換えて

 int n = 32768;
 int m, mq;
 for (m = n; (mq = m >> 2) >= 1; m = mq)
 {
   Console.WriteLine("m={0,7:N0}, mq={1,7:N0}", m, mq);
 }

として実行してみたところ
 m= 32,768, mq=  8,192
 m=  8,192, mq=  2,048
 m=  2,048, mq=    512
 m=    512, mq=    128
 m=    128, mq=     32
 m=     32, mq=      8
 m=      8, mq=      2
という結果になりました。

また、No91850 の実装なら、元の C++/C# 版と同じ結果が得られました。


一方、御提示頂いた No91848 の意訳実装で
 Dim n = 32768
 Dim m As Integer = n
 For g As Integer = 1 To CInt(Math.Log(n, 4))
  '
  Console.WriteLine("m={0,7:N0} =>", m)
  '
  m = CInt(m / 4)
  Dim mq As Integer = CInt(m / 4)
  '
  Console.WriteLine("m={0,7:N0}, mq={1,7:N0}", m, mq)
  '
 Next g
とした場合、出力結果はこうなりますね。ループ回数が変化しています。
 m= 32,768 => m=  8,192, mq=  2,048
 m=  8,192 => m=  2,048, mq=    512
 m=  2,048 => m=    512, mq=    128
 m=    512 => m=    128, mq=     32
 m=    128 => m=     32, mq=      8
 m=     32 => m=      8, mq=      2
 m=      8 => m=      2, mq=      0
 m=      2 => m=      0, mq=      0

引用返信 編集キー/
■91856 / inTopicNo.12)  Re[8]: C++からVBへの変換
□投稿者/ えん (9回)-(2019/08/07(Wed) 17:32:24)
内容を把握できていませんが。

意訳実装において
Forループの直後に
            m = CInt(m / 4)          
            Dim mq As Integer = CInt(m / 4)

を置きましたが
これは間違いで
Forループの最後に置く必要があることに気が付きました。


        Dim m As Integer = n
        Dim mq As Integer = m \ 4


        For g As Integer = 1 To CInt(Math.Log(n, 4))

~~~計算

            m = mq           'l → 256, 64, 16, 4, 1
            mq = m \ 4


        Next g

これなら問題ないと思いますがどうでしょうか?

引用返信 編集キー/
■91859 / inTopicNo.13)  Re[9]: C++からVBへの変換
□投稿者/ 魔界の仮面弁士 (2284回)-(2019/08/07(Wed) 18:18:41)
No91856 (えん さん) に返信
> これなら問題ないと思いますがどうでしょうか?


たとえば n = 8 であった場合:
 for (m = n; (mq = m >> 2) >= 1; m = mq)
 {
   // 処理
 }
は、「m=8, mq=2」の 1 回しか処理されません。

しかしながら、
 Dim m As Integer = n
 Dim mq As Integer = m \ 4
 For g As Integer = 1 To CInt(Math.Log(n, 4))
  ' 処理
  m = mq
  mq = m \ 4
 Next g
にすると、「m=8, mq=2」の後に「m=2, mq=0」で合計 2 回処理されてしまいますね。
引用返信 編集キー/
■91860 / inTopicNo.14)  Re[10]: C++からVBへの変換
□投稿者/ 魔界の仮面弁士 (2285回)-(2019/08/07(Wed) 18:34:45)
No91859 (魔界の仮面弁士) に追記
> にすると、「m=8, mq=2」の後に「m=2, mq=0」で合計 2 回処理されてしまいますね。

「m \ 4」を「CInt(m / 4)」に戻せば、
n = 8 の時の結果は合致しますね。

しかしそうすると、n = Int32.MaxValue の結果が変わってしまいますが。



引用返信 編集キー/
■91861 / inTopicNo.15)  Re[11]: C++からVBへの変換
□投稿者/ えん (10回)-(2019/08/07(Wed) 18:47:14)
上で述べたように
nは4のべき乗ですので
8は来ないはずですが・・

引用返信 編集キー/
■91862 / inTopicNo.16)  Re[12]: C++からVBへの変換
□投稿者/ えん (11回)-(2019/08/07(Wed) 19:25:57)
すいません、あと

    i = 0;
    for (j = 1; j < n - 1; j++) {
        for (k = n >> 1; k > (i ^= k); k >>= 1);
        if (j < i) {
            x0r = ar[j];
            x0i = ai[j];
            ar[j] = ar[i];
            ai[j] = ai[i];
            ar[i] = x0r;
            ai[i] = x0i;
        }
    }

この計算って


            Dim i_2 As Integer = 0

            For j As Integer = 1 To n - 2

                Dim k As Integer = n \ 2

                Do
                    i_2 = CInt(i_2 ^ k)

                    If k <= i_2 Then

                        Exit Do

                    ElseIf j < i_2 Then

                        Dim x0r As Double = xr(j)
                        Dim x0i As Double = xi(j)
                        xr(j) = xr(i_2)
                        xi(j) = xi(i_2)
                        xr(i_2) = x0r
                        xi(i_2) = x0i

                    End If

                    k \= 2

                Loop

            Next j

これで合っていますか?


どうやってもうまく計算できないのですが・・・



引用返信 編集キー/
■91867 / inTopicNo.17)  Re[13]: C++からVBへの変換
□投稿者/ KOZ (22回)-(2019/08/07(Wed) 22:19:50)
No91862 (えん さん) に返信
> for (k = n >> 1; k > (i ^= k); k >>= 1);

ここのループの解釈が違っているようです。
for 文はこれで完結しており、後ろの if は、このループの外にあります。
引用返信 編集キー/
■91869 / inTopicNo.18)  Re[14]: C++からVBへの変換
□投稿者/ えん (14回)-(2019/08/07(Wed) 22:43:03)
ありがとうございます。



Dim i_2 As Integer = 0

For j As Integer = 1 To n - 2

Dim k As Integer = n \ 2

Do
i_2 = CInt(i_2 ^ k)
If k <= i_2 Then Exit Do

k \= 2

Loop

If j < i_2 Then

Dim x0r As Double = xr(j)
Dim x0i As Double = xi(j)
xr(j) = xr(i_2)
xi(j) = xi(i_2)
xr(i_2) = x0r
xi(i_2) = x0i

End If

Next j



こういうことですか?

これでもなかうまくいかないのですが、
何が問題でしょうか?

引用返信 編集キー/
■91872 / inTopicNo.19)  Re[12]: C++からVBへの変換
□投稿者/ 魔界の仮面弁士 (2286回)-(2019/08/08(Thu) 00:00:29)
No91861 (えん さん) に返信
> nは4のべき乗ですので
> 8は来ないはずですが・・

あぁ、なるほど。

もしも n が任意の自然数だった場合には
> For g As Integer = 1 To CInt(Math.Log(n, 4))
ではなく
 For g As Integer = 1 To CInt(Int(Math.Log(n, 4)))
になるかも。



■No91862 (えん さん) に返信
> すいません、あと
> 
>     i = 0;
>     for (j = 1; j < n - 1; j++) {
>         for (k = n >> 1; k > (i ^= k); k >>= 1);
>         if (j < i) {
>             x0r = ar[j];
>             x0i = ai[j];
>             ar[j] = ar[i];
>             ai[j] = ai[i];
>             ar[i] = x0r;
>             ai[i] = x0i;
>         }
>     }


こうかな…? (未検証)


Dim i As Integer = 0
For j As Integer = 1 To n - 2
    ' Dim k As Integer = n >> 1
    Dim k As Integer = n \ 2

    i = i XOr k
    While k > i
        ' k >> = 1
        k \= 2
        i = i XOr k
    End While

    If j < i Then
       Dim swap_ar = ar(j)
       ar(j) = ar(i)
       ar(i) = swap_ar

       Dim swap_ai = ai(j)
       ai(j) = ai(i)
       ai(i) = swap_ai
    End If
Next

引用返信 編集キー/
■91882 / inTopicNo.20)  Re[13]: C++からVBへの変換
 
□投稿者/ えん (16回)-(2019/08/08(Thu) 11:27:22)
ありがとうございます。

できました。

^ をべき乗のことだと勘違いしていました
C++だとpowがべき乗になるのですね。

ちなみにXORって四則演算に置き換えることってできますでしょうか?

引用返信 編集キー/

このトピックをツリーで一括表示

次の20件>
トピック内ページ移動 / << 0 | 1 >>

管理者用

- Child Tree -