生成一个0到1之间的随机数
我试图产生一个介于0和1之间的随机数。我一直在阅读关于arc4random()
,但没有任何关于从它获得一个浮点数的信息。 我该怎么做呢?
[0,1 [ (包括0,不包括1)中的随机值:
#define ARC4RANDOM_MAX 0x100000000 ... double val = ((double)arc4random() / ARC4RANDOM_MAX);
这里有更多的细节。
实际范围为[0,0.999999999767169356] ,上限为(双)0xFFFFFFFF / 0x100000000。
// 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]上的非负双精度浮点值。
这个函数也适用于负的浮动范围:
float randomFloat(float Min, float Max){ return ((arc4random()%RAND_MAX)/(RAND_MAX*1.0))*(Max-Min)+Min; }
这里有正确的一致性和最佳精度的build议。
32位精度(最佳Float
)
在[0,1] (包括0.0和1.0)中的统一随机值,高达32位精度:
Obj-C :
float val = (float)arc4random() / UINT32_MAX;
Swift :
let val = Float(arc4random()) / Float(UInt32.max)
这是最佳的:
-
Float
(或Float
Float32
),其尾数有效位精度为24位
48位精度(不鼓励)
使用drand48
( arc4random_buf
下使用arc4random_buf
)很容易实现48位精度。 但是请注意, drand48由于种子要求而存在缺陷 ,并且对于双尾数的所有52位随机化也不是最理想的。
[0,1]中的统一随机值,48位精度:
Swift :
// seed (only needed once) srand48(Int(Date.timeIntervalSinceReferenceDate)) // random Double value let val = drand48()
64位精度(适用于Double
和Float80
)
在[0,1] (包括0.0和1.0)中的统一随机值,高达64位精度:
Swift ,使用两个调用arc4random:
let val = Float80(UInt64(arc4random()) << 32 &+ UInt64(arc4random())) / Float80(UInt64.max)
Swift ,使用一个调用arc4random_buf:
var arc4random64: UInt64 = 0 arc4random_buf(&arc4random64, MemoryLayout.size(ofValue: arc4random64)) let val = Float80(arc4random64) / Float80(UInt64.max)
这是最佳的:
- 一个
Double
(或Float64
),它的尾数的有效位精度为52位 - 其尾数有效位精度为64位的
Float80
笔记
与其他方法比较
答案范围是排除一个边界(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
或random
,在math上不可能实现比32位更好的精度。 所以我们以上的32位和64位解决scheme应该是我们能够实现的最好的。
(float)rand() / RAND_MAX
之前的文章中只声明“rand()”是不正确的。 这是使用rand()的正确方法。
这将创build一个0 – > 1之间的数字
BSD文档:
rand()函数计算一系列伪随机整数
范围从0到RAND_MAX(由头文件“stdlib.h”定义)。
这是Float随机数Swift 3.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 } }
使用这个来避免arc4random()的上界问题
u_int32_t upper_bound = 1000000; float r = arc4random_uniform(upper_bound)*1.0/upper_bound;
请注意,它适用于MAC_10_7,IPHONE_4_3及更高版本。
((CGFloat)(rand()%100)/100)
?
arc4random
的范围最大为0x100000000(4294967296)
这是生成0到1之间的随机数的另一个好的select:
srand48(time(0)); // pseudo-random number initializer. double r = drand48();
float x = arc4random() % 11 * 0.1;
这会产生0和1之间的随机漂移。 更多信息在这里
rand()
默认情况下产生一个0到1之间的随机数(浮点数)。