したがって、次のコードは0 <r <1になります
r = ((double) Rand() / (Rand_MAX))
r = ((double) Rand() / (Rand_MAX + 1))
が-1 <r <0になるのはなぜですか?
Rand_MAXに1を追加すると1 <r <2になりませんか?
編集:私は警告を受けていました:式の整数オーバーフロー
その行で、それが問題になるかもしれません。 cout << r << endl
を実行しましたが、-1〜0の値が確実に表示されます
これは完全に実装固有ですが、作業しているC++環境では、Rand_MAX
はINT_MAX
と等しいようです。
このため、Rand_MAX + 1
は未定義の(オーバーフロー)動作を示し、INT_MIN
になります。最初のステートメントは分割(0からINT_MAX
の間のランダム#)と(INT_MAX
)で値0 <= r < 1
を生成していましたが、現在は分割(0からINT_MAX
の間のランダム#)/(INT_MIN
)で値-1 < r <= 0
を生成しています
乱数1 <= r < 2
を生成するには、次のようにします
r = ((double) Rand() / (Rand_MAX)) + 1
Rand() / double(Rand_MAX)
は、0(包括的)から1(包括的)の間の浮動小数点乱数を生成しますが、以下には適していません理由(Rand_MAXは通常32767であるため):
Rand()の上記の制限により、0(包括的)から1(exclusive)の間の乱数生成のより良い選択は次のようになります。スニペット( http://en.cppreference.com/w/cpp/numeric/random/uniform_real_distribution の例と同様):
#include <iostream>
#include <random>
#include <chrono>
int main()
{
std::mt19937_64 rng;
// initialize the random number generator with time-dependent seed
uint64_t timeSeed = std::chrono::high_resolution_clock::now().time_since_Epoch().count();
std::seed_seq ss{uint32_t(timeSeed & 0xffffffff), uint32_t(timeSeed>>32)};
rng.seed(ss);
// initialize a uniform distribution between 0 and 1
std::uniform_real_distribution<double> unif(0, 1);
// ready to generate random numbers
const int nSimulations = 10;
for (int i = 0; i < nSimulations; i++)
{
double currentRandomNumber = unif(rng);
std::cout << currentRandomNumber << std::endl;
}
return 0;
}
unif(0, 1)
をunif(1, 2)
に置き換えることにより、1(包括的)から2(排他的)の間の乱数を生成するように簡単に変更できます。
いいえ、Rand_MAXは通常MAX_INTに拡張されるためです。そのため、1つ(明らかに)を追加すると、MIN_INTに配置されます(ただし、私が言ったように未定義の動作であるはずです)。したがって、符号が反転します。
必要なものを取得するには、計算の外側に+1を移動する必要があります。
r = ((double) Rand() / (Rand_MAX)) + 1;
そうではありません。 0 <= r < 1
になりますが、オリジナルは0 <= r <= 1
です。
これは、Rand_MAX + 1
がオーバーフローした場合に未定義の動作につながる可能性があることに注意してください。
私の推測では、Rand_MAX
はINT_MAX
と等しいので、負の値にオーバーフローしています。
これを行うだけです:
r = ((double) Rand() / (Rand_MAX)) + 1;
さらに良いことに、C++ 11の乱数ジェネレーターを使用します。
これは正しい方法です:
double randd() {
return (double)Rand() / ((double)Rand_MAX + 1);
}
または
double randd() {
return (double)Rand() / (Rand_MAX + 1.0);
}
私の場合(私はVS 2017を使用しています)、次の簡単なコードでうまく動作します:
#include "pch.h"
#include <iostream>
#include <stdlib.h>
#include <time.h>
int main()
{
srand(time(NULL));
for (int i = 1000; i > 0; i--) //try it thousand times
{
int randnum = (double)Rand() / ((double)Rand_MAX + 1);
std::cout << " rnum: " << Rand()%2 ;
}
}