質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.36%

vba

解決済

回答 2

投稿

  • 評価
  • クリップ 0
  • VIEW 1,050
退会済みユーザー

退会済みユーザー

前提・実現したいこと

現在Visual basicのプログラムをC言語に書き換えています
そこでRandomizeの関数がでてくるのですが、これをどのように書き換えればいいのかわかりません
自分なりにプログラムを作りましたが、同じような値が出力されません
特にわからない箇所が
Randomize4の意味は毎回同じシートを使って乱数を指定しているので乱数の出方のパターンは同じということですか?
また、Rnd1とRnd2に代入される乱数は同じ値ですか?

最終的にはこの部分と同じプログラムをC言語で書きたいです
なので書き換えの部分で変な箇所があればどのように直すのか教えていただきたいです

Visual basic
以下はプログラムの途中部分です
Randomize 4
    PI = 4 * Atn(1)
    For i = 1 To N / 2 - 1
        For j = 1 To N / 2 - 1

            If i <> 0 Or j <> 0 Then

            kx = i / (region)
            ky = j / (region)
            K = Sqr(kx ^ 2 + ky ^ 2)
            Rnd1 = Rnd
            Rnd2 = Rnd

            gauss = Abs(Sqr(-2 * Log(Rnd1)) * Cos(2 * PI * Rnd2))

             '************************
             'gaussの上限,下限 (04.6.20)

                If gauss < 0.001 Then
                    gauss = 0.001
                ElseIf gauss > 10 Then
                    gauss = 10
                End If
             '************************

            Spec = ParaA1 * (K ^ (-ParaB1))
            Spec2 = Spec * (gauss ^ flag)
            rad = Sqr(Spec2 * 0.25)

               If Sqr(kx ^ 2 + ky ^ 2) >= lim Then
                  phase = PI / 2
               Else
                  phase = 2 * PI * Rnd
               End If

            A(i, j) = rad * Cos(phase)
            B(i, j) = rad * Sin(phase)
            A(N - i - 1, N - j - 1) = rad * Cos(phase)
            B(N - i - 1, N - j - 1) = rad * Sin(phase)
            A(i, N - j - 1) = rad * Cos(phase)
            B(i, N - j - 1) = rad * Sin(phase)
            A(N - i - 1, j) = rad * Cos(phase)
            B(N - i - 1, j) = rad * Sin(phase)
            End If

以下C言語の書き換えです
visual basicでRnd1,Rnd2に代入される乱数が同じとして作ってみました
  srand(3);
  pi=4*atan(1)
  rnd = (double)rand()/RAND_MAX;
  for(i = 0;i <= n/2-1;i++){
    for(j = 0;j <= n/2-1;j++){
      kx = i/region;
      ky = j/region;
      k = sqrt(kx*kx + ky*ky);
      gauss = fabs( sqrt(-2 * log(rnd)) * cos(2 * pi * rnd) );
/*gaussの上限,下限 (04.6.20)*/
      if(gauss < 0.001){
        gauss = 0.001;
      }else{
        if(gauss > 10){
          gauss = 10;
        }
       }

      if(k == 0){
        spec = 1000;
      }else{
        spec = paraa1 * pow(k,-parab1);
       }

      spec2 = spec * pow(gauss,flag);
      rad = sqrt(spec2 * 0.25);
      if(sqrt(kx*kx + ky*ky) >= lim){
        phase = pi / 2;
      }else{
         phase = 2 * pi * rnd;
       }

      a[i][j] = rad * cos(phase);
      b[i][j] = rad * sin(phase);
      a[n-i-1][n-j-1] = rad * cos(phase);
      b[n-i-1][n-j-1] = rad * sin(phase);
      a[i][n-j-1] = rad * cos(phase);
      b[i][n-j-1] = rad * sin(phase);
      a[n-i-1][j] = rad * cos(phase);
      b[n-i-1][j] = rad * sin(phase);
    }
  }

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

checkベストアンサー

+1

Randomize4の意味は毎回同じシートを使って乱数を指定しているので乱数の出方のパターンは同じということですか? 

そうです。

また、Rnd1とRnd2に代入される乱数は同じ値ですか? 

違います。Rndは関数なので、使う度に異なる値が返ってきます。

VBのRndは変数のように見えますが関数なので、当然C言語側もRndが書かれていた場所で乱数を取得しないといけません。

rnd()関数を用意します。

double rnd(void)
{
    return (double)rand()/RAND_MAX;
}


VBのRnd関数を使っている箇所をrnd()関数に置き換えます。

// gaussの計算のところ
gauss = fabs( sqrt(-2 * log(rnd())) * cos(2 * pi * rnd()) );

// 中略

// phaseの計算のところ
phase = 2 * pi * rnd();


ループ手前のrnd = (double)rand()/RAND_MAX;は不要なので削除してください。変数宣言も削除してください。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/05/27 23:54

    printf("i=%d ", i);をfor文の直後においたらなぜかkxが出ました

    キャンセル

  • 2016/05/28 00:04

    あ、よく見たらprintfに改行がないですね。`printf("i=%d\n", i);`のように、書式の最後に改行(\n)を入れてみてください。

    キャンセル

  • 2016/05/29 00:12

    わかりました
    ありがとうございます
    やってみます

    キャンセル

0

擬似乱数の生成には様々なアルゴリズムがあり、同じ数列を得るためには、同じアルゴリズムと同じシード値を使わなければなりません。

「visual basic Rnd 関数」というキーワードで検索したところ、運良く、以下のページを見つけました。

ここに Rnd 関数で使われているアルゴリズムと、それを C で再現するコードが載っていました。これを参考に実装してみてください。

一応、機械翻訳されたページもありますが、日本語がいろいろと怪しいです。


Randomize4の意味は毎回同じシートを使って乱数を指定しているので乱数の出方のパターンは同じということですか? 

そのようですね。

また、Rnd1とRnd2に代入される乱数は同じ値ですか?

引数なしで Rnd を呼んでいますので、違う値になると思います。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/05/27 21:36

    回答ありがとうございます
    Randomizeの理解が深まりました!
    紹介してくださったページをみながら書き換えてみようと思います!

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.36%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る