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

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

ログ内検索
  • キーワードを複数指定する場合は 半角スペース で区切ってください。
  • 検索条件は、(AND)=[A かつ B] (OR)=[A または B] となっています。
  • [返信]をクリックすると返信ページへ移動します。
キーワード/ 検索条件 /
検索範囲/ 強調表示/ ON (自動リンクOFF)
結果表示件数/ 記事No検索/ ON
大文字と小文字を区別する

No.91938 の関連記事表示

<< 0 >>
■91938  Re[16]: C++からVBへの変換
□投稿者/ 魔界の仮面弁士 -(2019/08/12(Mon) 12:05:54)
    2019/08/12(Mon) 13:21:00 編集(投稿者)

    No91934 (えんえん さん) に返信
    > 何が間違っていますでしょうか?

    『ステップ実行』しましょう。

    ループ処理などを一行ずつ実行してみた上で、

      この場所では、この変数に
      こういう値がセットされるはずなのに、
      実際にはこんな値になってしまった
     」
    …という点を追跡できれば、どこの翻訳実装に問題があったことが明確になりますよね。


    > とりあえず、先に ArraySegmentを使った方法を試してみました。

    何か所か間違いがありますが、まずはここ。
     tmpr[m * n_radix + j] = xr * wr - xi * wi;

    No91934 のコードでは、上記を
    > tmpr.Array(m * n_radix + j) = xr * wr - xi * wi
    と翻訳してしまっていますので、ここが大きな間違いです。

    たとえば、
     Dim x() As Byte = New Byte(5) {11, 22, 33, 44, 55, 66}
     Dim y As New ArraySegment(Of Byte)(x)
     Dim z As New ArraySegment(Of Byte)(x, 2, 3)
    において、「y.Array」や「z.Array」は、配列 x への参照を意味します。
    ※ Span も似たようなものですが、Span はさらに各要素への参照も持ちます。

    なので、x(3) = 100 と代入すれば、z(1) も同様に 44 から 100 へと変化します。

    この時、それぞれの要素を列挙すれば
     x は {11, 22, 33, 100, 55, 66} 相当 (y.Array や z.Array も同様)
     y は {11, 22, 33, 100, 55, 66} 相当 (y.Offset は 0、y.Count は 6)
     z は {33, 100, 55} 相当 (z.Offset は 2、z.Count は 3)
    となります。
    Array / Offset / Count プロパティの 3 セットが、この構造体の肝です。
    ここまでは良いでしょうか。


    ArraySegment 構造体の場合、値の取得については
     MsgBox( z(i) )
    のように書けるのですが、問題は書き込みです。インデクサが ReadOnly なので、
     z(i) = newValue
    のようには書けません。(Span 構造体なら可能になるはず)

    そのため、オフセット指定の書き込みが必要な場合には、
     z.Array(z.Offset + i) = newValue
    のように、Array プロパティと Offset プロパティを併用することになります。
    No91934 のコードでは、この点が考慮されていないように見受けられます。


    =====

    それと、むやみに ByRef を使わないでください。
    今回は出力引数が存在しないため、ByRef の出番は一切ありません。

    先にも述べましたが、出力引数が必要な場合以外は、値渡しで実装するべきです。



    Sub Main()
      Dim x() As Byte = New Byte(3) {&H11, &H22, &HAB, &HCD}
      MsgBox(BitConverter.ToString(x))

      'AsSegment については No91917 を参照
      Test(x.AsSegment())
      MsgBox(BitConverter.ToString(x))

      Test(x.AsSegment(2, 2))
      MsgBox(BitConverter.ToString(x))
    End Sub

    ' a(0) と a(1) の中身を入れ替える処理
    ' この時、引数 ArraySegment 構造体を ByRef にする必要は無い!
    Sub Test(Of T)(ByVal a As ArraySegment(Of T))
      Dim swap() As T = {a(0), a(1)}
      a.Array(a.Offset + 1) = swap(0)
      a.Array(a.Offset + 0) = swap(1)
    End Sub


    ※ 先の No91917 ですが、最後の End Function が誤って End Sub になっていました。
     恐れ入りますが、 End Function に読み替えておいてください。


    > Public Sub one_D_FFT(ByRef xr#(), ByRef xi#())
    > Private Sub fft(ByVal n%, ByVal theta#, ByRef ar As ArraySegment(Of Double), ByRef ai As ArraySegment(Of Double), ByRef tmpr As ArraySegment(Of Double), ByRef tmpi As ArraySegment(Of Double))

    これらについて、メソッド名を分ける必要は無いと思います。オーバーロードで十分ではないでしょうか。
     Public Sub Fft(xr#(), xi#())
     Private Sub Fft(n%, theta#, ar As ArraySegment(Of Double), ar As ArraySegment(Of Double), tmpr As ArraySegment(Of Double), tmpi As ArraySegment(Of Double))


    メソッド名を分けるにしても、両者でメソッド名の大文字小文字の使い分けが不揃いな点が気にかかります。
    .NET Framework においては一般的に、
      ・クラス名やメソッド名は PascalCase 構文の大文字小文字表記とする。
      ・変数や引数は、camelCase 構文の大文字小文字表記とする。
    というのが一般的ですので、この点を意識したコーディングにされることをお奨めします。
    https://docs.microsoft.com/ja-jp/dotnet/standard/design-guidelines/naming-guidelines
    http://objectclub.jp/community/codingstandard/CodingStdVB.doc
記事No.91899 のレス /過去ログ158より / 関連記事表示
削除チェック/



<< 0 >>

パスワード/

- Child Tree -