生成0到1之间的随机浮点数

时间:2011-03-02 19:32:21

标签: ios c random floating-point arc4random

我正在尝试生成一个介于0和1之间的随机数。我一直在阅读arc4random(),但是没有任何关于从中获取浮点数的信息。我该怎么做?

13 个答案:

答案 0 :(得分:134)

[0,1 [(包括0,不包括1)中的随机值:

#define ARC4RANDOM_MAX      0x100000000
...
double val = ((double)arc4random() / ARC4RANDOM_MAX);

更多细节here

实际范围是 [0,0.999999999767169356] ,因为上限是(double)0xFFFFFFFF / 0x100000000。

答案 1 :(得分:105)

// 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]上。

答案 2 :(得分:13)

对于Swift 4.2 +,请参阅:https://stackoverflow.com/a/50733095/1033581

以下是ObjC和Swift 4.1的正确均匀性和最佳精度的建议。

32位精度(最适合Float

[0,1] (包括0.0和1.0)中的均匀随机值,最高32位精度:

<强>的OBJ-C

float val = (float)arc4random() / UINT32_MAX;

<强>夫特

let val = Float(arc4random()) / Float(UInt32.max)

最适合:

  • a Float(或Float32),其尾数的有效位精度为24位

48位精度(不鼓励)

使用drand48which uses arc4random_buf under the hood)很容易实现48位精度。但是请注意drand48 has flaws因为种子要求而且不是最优的随机化所有52位双尾数。

[0,1] 中的统一随机值,48位精度:

<强>夫特

// seed (only needed once)
srand48(Int(Date.timeIntervalSinceReferenceDate))
// random Double value
let val = drand48()

64位精度(最适合DoubleFloat80

[0,1] (包括0.0和1.0)中的均匀随机值,最高64位精度:

Swift ,使用两次对arc4random的调用:

let arc4random64 = UInt64(arc4random()) << 32 &+ UInt64(arc4random())
let val = Float80(arc4random64) / 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位
  • a Float80,其尾数的有效位精度为64位

注释

与其他方法的比较

范围排除其中一个边界(0或1)的答案可能会受到均匀性偏差的影响,应该避免。

  • 使用arc4random(),最佳精度为1 / 0xFFFFFFFF(UINT32_MAX)
  • 使用arc4random_uniform(),最佳精度为1 / 0xFFFFFFFE(UINT32_MAX-1)
  • 使用rand()secretly using arc4random),最佳精度为1 / 0x7FFFFFFF(RAND_MAX)
  • 使用random()secretly using arc4random),最佳精度为1 / 0x7FFFFFFF(RAND_MAX)

通过一次调用arc4randomarc4random_uniformrandrandom,在数学上不可能达到32位精度。因此,我们的32位和64位解决方案应该是我们能够实现的最佳解决方案。

答案 3 :(得分:10)

此函数也适用于负浮点范围:

float randomFloat(float Min, float Max){
    return ((arc4random()%RAND_MAX)/(RAND_MAX*1.0))*(Max-Min)+Min;
}

答案 4 :(得分:4)

Swift 4.2 +

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)

文档:

答案 5 :(得分:1)

(float)rand() / RAND_MAX

单独说明“rand()”的帖子不正确。 这是使用rand()的正确方法。

这将创建一个介于0 - >之间的数字。 1

  

BSD文档:

     

rand()函数计算
中的一系列伪随机整数   范围为0到RAND_MAX(由头文件“stdlib.h”定义)。

答案 6 :(得分:1)

这是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
    }
}

答案 7 :(得分:1)

Swift 4.2

Swift 4.2在标准库中包含了一个原生的,功能齐全的随机数API。 (Swift Evolution proposal SE-0202

let intBetween0to9 = Int.random(in: 0...9) 
let doubleBetween0to1 = Double.random(in: 0...1)

所有数字类型都有静态random(in:)函数,该函数取范围并返回给定范围内的随机数。

答案 8 :(得分:0)

使用此选项可避免 arc4random()

的上限出现问题
u_int32_t upper_bound = 1000000;

float r = arc4random_uniform(upper_bound)*1.0/upper_bound;

请注意,它适用于MAC_10_7,IPHONE_4_3及更高版本。

答案 9 :(得分:-1)

此操作如何((CGFloat)(rand()%100)/100)

答案 10 :(得分:-1)

arc4random的范围最高为0x100000000(4294967296)

这是生成0到1之间随机数的另一个好选择:

srand48(time(0));      // pseudo-random number initializer.
double r = drand48();

答案 11 :(得分:-4)

float x = arc4random() % 11 * 0.1;

产生0到1之间的随机浮点数。 More info here

答案 12 :(得分:-4)

rand() 
默认情况下,

会产生0到1之间的随机数(浮点数)。

相关问题