0 から 1 の間の乱数を生成しようとしてarc4random()
います。どうすればいいですか?
12 に答える
[0, 1[ (0 を含み、1 を除く)内のランダムな値:
double val = ((double)arc4random() / UINT32_MAX);
ここでもう少し詳しく説明します。
実際の範囲は[0, 0.999999999767169356]で、上限は (double)0xFFFFFFFF / 0x100000000 です。
Swift 4.2+ については、https ://stackoverflow.com/a/50733095/1033581 を参照してください。
以下は、ObjC と Swift 4.1 の正確な均一性と最適な精度に関する推奨事項です。
32 ビット精度 ( に最適Float
)
[0, 1] (0.0 と 1.0 を含む) の一様ランダム値、最大 32 ビット精度:
オブジェクト C :
float val = (float)arc4random() / UINT32_MAX;
スウィフト:
let val = Float(arc4random()) / Float(UInt32.max)
次の場合に最適です。
- 仮数部の有効桁数精度が 24 ビットのa
Float
(または)Float32
48 ビット精度 (非推奨)
drand48
(内部で使用するarc4random_buf
) を使用して 48 ビットの精度を達成するのは簡単です。ただし、drand48 には、シード要件があり、Double 仮数部の 52 ビットすべてをランダム化するのに最適ではないため、欠陥があることに注意してください。
[0, 1]の一様ランダム値、48 ビット精度:
スウィフト:
// seed (only needed once)
srand48(Int(Date.timeIntervalSinceReferenceDate))
// random Double value
let val = drand48()
Double
64 ビット精度 (および に最適Float80
)
[0, 1] (0.0 と 1.0 を含む) の一様ランダム値、最大 64 ビット精度:
Swift、arc4random への 2 つの呼び出しを使用:
let arc4random64 = UInt64(arc4random()) << 32 &+ UInt64(arc4random())
let val = Float80(arc4random64) / Float80(UInt64.max)
Swift、arc4random_buf への 1 つの呼び出しを使用:
var arc4random64: UInt64 = 0
arc4random_buf(&arc4random64, MemoryLayout.size(ofValue: arc4random64))
let val = Float80(arc4random64) / Float80(UInt64.max)
次の場合に最適です。
- a
Double
(またはFloat64
) 仮数部の仮数精度が 52 ビットである Float80
仮数部の有効桁数の精度が 64 ビットのa
ノート
他の方法との比較
範囲が境界の 1 つ (0 または 1) を除外している回答は、均一性バイアスに苦しむ可能性が高いため、避ける必要があります。
- を使用する
arc4random()
と、最高精度は 1 / 0xFFFFFFFF (UINT32_MAX) - を使用する
arc4random_uniform()
と、最高の精度は 1 / 0xFFFFFFFE (UINT32_MAX-1) rand()
(ひそかに arc4random を使用)を使用すると、最高の精度は 1 / 0x7FFFFFFF (RAND_MAX) です。random()
(ひそかに arc4random を使用)を使用すると、最高の精度は 1 / 0x7FFFFFFF (RAND_MAX) です。
arc4random
、arc4random_uniform
、rand
またはへの 1 回の呼び出しで 32 ビットを超える精度を達成することは、数学的に不可能random
です。したがって、上記の 32 ビットおよび 64 ビットのソリューションは、達成できる最善のソリューションです。
この関数は、負の float 範囲でも機能します。
float randomFloat(float Min, float Max){
return ((arc4random()%RAND_MAX)/(RAND_MAX*1.0))*(Max-Min)+Min;
}
(float)rand() / RAND_MAX
「rand()」だけを述べた以前の投稿は誤りでした。これは、rand() を使用する正しい方法です。
これにより、0 -> 1 の間の数値が作成されます
BSD ドキュメント:
rand() 関数は、0 から RAND_MAX (ヘッダー ファイル "stdlib.h" で定義)の範囲の疑似乱数整数のシーケンスを計算します。
rand()
デフォルトでは、0から1の間の乱数(float)が生成されます。
float x = arc4random() % 11 * 0.1;
これにより、0 と 1 の間のランダムな float が生成されます 。詳細はこちら