0から1の間の乱数を生成しようとしています。について読み続けてarc4random()
いますが、フロートを取得するための情報がありません。どうすればよいですか?
回答:
[0、1 [のランダム値(0を含み、1を除く):
double val = ((double)arc4random() / UINT32_MAX);
ここでもう少し詳細。
上限が(double)0xFFFFFFFF / 0x100000000であるため、実際の範囲は[ 0、0.9999999999767169356]です。
ARC4RANDOM_MAX
手動で定義する必要があるのは奇妙ですが、0x100000000
4294967296ですULONG_MAX + 1
。とにかくarc4random()
の最大値はどこに文書化されていULONG_MAX
ますか?
// Seed (only once)
srand48(time(0));
double x = drand48();
// Swift version
// Seed (only once)
srand48(Int(Date().timeIntervalSince1970))
let x = drand48()
drand48()およびerand48()関数は、区間[0.0、1.0]に均一に分散された、非負の倍精度浮動小数点値を返します。
drand48
。アップルのドキュメントでは、それが初期化されなければならないことを示唆しています。
double
。最高の精度を達成する方法については、stackoverflow.com / a / 34765674/1033581を参照してください。
Swift 4.2以降については、https://stackoverflow.com/a/50733095/1033581を参照してください。
以下は、ObjCとSwift4.1の正しい均一性と最適な精度に関する推奨事項です。
Float
)[0、1]の一様ランダム値(0.0および1.0を含む)、最大32ビットの精度:
Obj-C:
float val = (float)arc4random() / UINT32_MAX;
スイフト:
let val = Float(arc4random()) / Float(UInt32.max)
次の場合に最適です。
Float
(またはFloat32
その仮数部24ビットの有効数字の精度を有します)drand48
(内部で使用arc4random_buf
する)を使用すると、48ビットの精度を簡単に実現できます。ただし、drand48には欠陥があることに注意してください、シード要件と、52ビットすべてのダブル仮数をランダム化するのに最適でためにことに。
[0、1]の一様ランダム値、48ビット精度:
スイフト:
// seed (only needed once)
srand48(Int(Date.timeIntervalSinceReferenceDate))
// random Double value
let val = drand48()
Double
およびに最適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)
次の場合に最適です。
Double
(またはFloat64
その仮数部52ビットの有効数字の精度を有します)Float80
その仮数部64ビットの仮数精度を有します範囲が境界の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)です。これは、単一の呼び出しで、より良いよりも32ビット精度を達成するために、数学的に不可能だarc4random
、arc4random_uniform
、rand
またはrandom
。したがって、上記の32ビットおよび64ビットのソリューションは、達成できる最善の方法である必要があります。
この関数は、負のフロート範囲でも機能します。
float randomFloat(float Min, float Max){
return ((arc4random()%RAND_MAX)/(RAND_MAX*1.0))*(Max-Min)+Min;
}
Min+(Max-Min)*((float)arc4random())/ULONG_MAX
代わりに使用してください。(float)
キャストはちょうどパラノイアです。
Swift 4.2は、範囲内のランダム値のネイティブサポートを追加します。
let x = Float.random(in: 0.0...1.0)
let y = Double.random(in: 0.0...1.0)
let z = Float80.random(in: 0.0...1.0)
Doc:
(float)rand() / RAND_MAX
「rand()」だけを述べた以前の投稿は正しくありませんでした。これは、rand()を使用する正しい方法です。
これにより、0-> 1の間の数値が作成されます
BSDドキュメント:
rand()関数
は、0からRAND_MAXの範囲の疑似乱数整数のシーケンスを計算します(ヘッダーファイル "stdlib.h"で定義されています)。
これは、Float乱数Swift3.1の拡張機能です。
// MARK: Float Extension
public extension Float {
/// Returns a random floating point number between 0.0 and 1.0, inclusive.
public static var random: Float {
return Float(arc4random()) / Float(UInt32.max))
}
/// Random float between 0 and n-1.
///
/// - Parameter n: Interval max
/// - Returns: Returns a random float point number between 0 and n max
public static func random(min: Float, max: Float) -> Float {
return Float.random * (max - min) + min
}
}
Swift 4.2
Swift 4.2には、ネイティブでかなりフル機能の乱数APIが標準ライブラリに含まれています。(Swift EvolutionプロポーザルSE-0202)
let intBetween0to9 = Int.random(in: 0...9)
let doubleBetween0to1 = Double.random(in: 0...1)
すべての数値タイプには、範囲を取得して指定された範囲の乱数を返す静的random(in :)関数があります。
これを使用して、arc4random()の上限に関する問題を回避します。
u_int32_t upper_bound = 1000000;
float r = arc4random_uniform(upper_bound)*1.0/upper_bound;
MAC_10_7、IPHONE_4_3以降に適用できることに注意してください。
upper_bound-1
ます。それでも、upper_boundが原因で精度が任意に低くなるため、upper_boundをUINT32_MAXに増やす必要があります。また、のarc4random()*1.0 / UINT32_MAX
代わりにを使用すると、さらに高い精度を得ることができますarc4random_uniform(UINT32_MAX)*1.0 / (UINT32_MAX-1)
。
arc4random
最大範囲は0x100000000(4294967296)
これは、0から1までの乱数を生成するためのもう1つの優れたオプションです。
srand48(time(0)); // pseudo-random number initializer.
double r = drand48();
float x = arc4random() % 11 * 0.1;
これにより、0と1の間にランダムなフロートが生成されます 。詳細はこちら
rand()
デフォルトでは、0から1の間の乱数(float)が生成されます。
rand()
はCの一部であり、CはObjective-C(iOSプログラミングで使用されます)の一部です。C関数rand()
はiOSに絶対に存在しますが、arc4random()
推奨されます。