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

发布于 2024-10-19 17:44:23 字数 95 浏览 8 评论 0原文

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

I'm trying to generate a random number that's between 0 and 1. I keep reading about arc4random(), but there isn't any information about getting a float from it. How do I do this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(12

Saygoodbye 2024-10-26 17:44:23

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

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

更多详细信息 此处

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

Random value in [0, 1[ (including 0, excluding 1):

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

A bit more details here.

Actual range is [0, 0.999999999767169356], as upper bound is (double)0xFFFFFFFF / 0x100000000.

烟酉 2024-10-26 17:44:23
// 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] 上。

// Seed (only once)
srand48(time(0));

double x = drand48();

// Swift version
// Seed (only once)
srand48(Int(Date().timeIntervalSince1970))

let x = drand48()

The drand48() and erand48() functions return non-negative, double-precision, floating-point values, uniformly distributed over the interval [0.0 , 1.0].

奶茶白久 2024-10-26 17:44:23

对于 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;

Swift

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

最适合:

  • 的有效数精度为 24 位的 Float(或 Float32

尾数48 位精度(不鼓励)

使用 drand48 可以轻松实现 48 位精度(在底层使用 arc4random_buf)。但请注意 drand48 有缺陷,因为种子要求以及随机化所有 52 位双尾数的次优结果。

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

Swift

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

64 位精度(最适合 DoubleFloat80< /code>)

[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 位
  • < code>Float80 其尾数的有效数精度为 64 位

注释

与其他方法的比较

范围不包括边界之一(0 或 1)的答案可能会受到均匀性偏差的影响,应避免。

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

从数学上讲,通过一次调用 arc4random< 不可能达到高于 32 位的精度/code>、arc4random_uniformrandrandom。所以我们上面的32位和64位解决方案应该是我们能实现的最好的。

For Swift 4.2+ see: https://stackoverflow.com/a/50733095/1033581


Below are recommendations for correct uniformity and optimal precision for ObjC and Swift 4.1.

32 bits precision (Optimal for Float)

Uniform random value in [0, 1] (including 0.0 and 1.0), up to 32 bits precision:

Obj-C:

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

Swift:

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

It's optimal for:

  • a Float (or Float32) which has a significand precision of 24 bits for its mantissa

48 bits precision (discouraged)

It's easy to achieve 48 bits precision with drand48 (which uses arc4random_buf under the hood). But note that drand48 has flaws because of the seed requirement and also for being suboptimal to randomize all 52 bits of Double mantissa.

Uniform random value in [0, 1], 48 bits precision:

Swift:

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

64 bits precision (Optimal for Double and Float80)

Uniform random value in [0, 1] (including 0.0 and 1.0), up to 64 bits precision:

Swift, using two calls to arc4random:

let arc4random64 = UInt64(arc4random()) << 32 &+ UInt64(arc4random())
let val = Float80(arc4random64) / Float80(UInt64.max)

Swift, using one call to arc4random_buf:

var arc4random64: UInt64 = 0
arc4random_buf(&arc4random64, MemoryLayout.size(ofValue: arc4random64))
let val = Float80(arc4random64) / Float80(UInt64.max)

It's optimal for:

  • a Double (or Float64) which has a significand precision of 52 bits for its mantissa
  • a Float80 which has a significand precision of 64 bits for its mantissa

Notes

Comparisons with other methods

Answers where the range is excluding one of the bounds (0 or 1) likely suffer from a uniformity bias and should be avoided.

  • using arc4random(), best precision is 1 / 0xFFFFFFFF (UINT32_MAX)
  • using arc4random_uniform(), best precision is 1 / 0xFFFFFFFE (UINT32_MAX-1)
  • using rand() (secretly using arc4random), best precision is 1 / 0x7FFFFFFF (RAND_MAX)
  • using random() (secretly using arc4random), best precision is 1 / 0x7FFFFFFF (RAND_MAX)

It's mathematically impossible to achieve better than 32 bits precision with a single call to arc4random, arc4random_uniform, rand or random. So our above 32 bits and 64 bits solutions should be the best we can achieve.

倾城泪 2024-10-26 17:44:23

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

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

This function works for negative float ranges as well:

float randomFloat(float Min, float Max){
    return ((arc4random()%RAND_MAX)/(RAND_MAX*1.0))*(Max-Min)+Min;
}
迎风吟唱 2024-10-26 17:44:23

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)

文档:

Swift 4.2+

Swift 4.2 adds native support for a random value in a Range:

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:

蓝颜夕 2024-10-26 17:44:23
(float)rand() / RAND_MAX

上一篇文章单独指出“rand()”是不正确的。
这是使用 rand() 的正确方法。

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

BSD 文档:

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

(float)rand() / RAND_MAX

The previous post stating "rand()" alone was incorrect.
This is the correct way to use rand().

This will create a number between 0 -> 1

BSD docs:

The rand() function computes a sequence of pseudo-random integers in the
range of 0 to RAND_MAX (as defined by the header file "stdlib.h").

回梦 2024-10-26 17:44:23

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

This is extension for Float random number 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
    }
}
怪我鬧 2024-10-26 17:44:23

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:) 函数它获取范围并返回给定范围内的随机数。

Swift 4.2

Swift 4.2 has included a native and fairly full-featured random number API in the standard library. (Swift Evolution proposal SE-0202)

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

All number types have the static random(in:) function which takes the range and returns the random number in the given range.

泪意 2024-10-26 17:44:23

使用它可以避免 arc4random() 上限出现问题。

u_int32_t upper_bound = 1000000;

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

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

Use this to avoid problems with upper bound of arc4random()

u_int32_t upper_bound = 1000000;

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

Note that it is applicable for MAC_10_7, IPHONE_4_3 and higher.

旧情勿念 2024-10-26 17:44:23

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

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

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

arc4random has a range up to 0x100000000 (4294967296)

This is another good option to generate random numbers between 0 to 1:

srand48(time(0));      // pseudo-random number initializer.
double r = drand48();
兮颜 2024-10-26 17:44:23
float x = arc4random() % 11 * 0.1;

这会产生 0 和 1 之间的随机浮点数。
更多信息在这里

float x = arc4random() % 11 * 0.1;

That produces a random float bewteen 0 and 1.
More info here

不美如何 2024-10-26 17:44:23
rand() 

默认情况下生成 0 到 1 之间的随机数(浮点数)。

rand() 

by default produces a random number(float) between 0 and 1.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文