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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5172421/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 19:06:14  来源:igfitidea点击:

Generate a random float between 0 and 1

ioscrandomfloating-pointarc4random

提问by jini

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?

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

回答by Vladimir

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

[0, 1[ 中的随机值(含0,不含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.

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

回答by Jovan Stankovic

// 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].

drand48() 和 erand48() 函数返回在区间 [0.0 , 1.0] 上均匀分布的非负双精度浮点值。

回答by C?ur

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

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



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

以下是为 ObjC 和 Swift 4.1 提供正确一致性和最佳精度的建议。

32 bits precision (Optimal for Float)

32 位精度(最适合Float

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

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

Obj-C:

对象-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
  • a Float(or Float32) 其尾数的有效位精度为 24 位

48 bits precision (discouraged)

48 位精度(不鼓励)

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

这很容易实现与48位精度drand48其使用arc4random_buf罩下)。但请注意,drand48 存在缺陷,因为它需要种子,并且在随机化双尾数的所有 52 位时也不是最理想的。

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

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

Swift:

斯威夫特

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

64 bits precision (Optimal for Doubleand Float80)

64 位精度(最适合DoubleFloat80

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

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

Swift, using two calls to arc4random:

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

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

Swift, using one call to arc4random_buf:

Swift,使用对 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 Float80which has a significand precision of 64 bits for its mantissa
  • a Double(or Float64) 其尾数的有效位精度为 52 位
  • aFloat80其尾数的有效位精度为 64 位


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.

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

  • 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)
  • 使用arc4random(),最佳精度为 1 / 0xFFFFFFFF (UINT32_MAX)
  • 使用arc4random_uniform(),最佳精度为 1 / 0xFFFFFFFE (UINT32_MAX-1)
  • 使用rand()秘密使用 arc4random),最佳精度为 1 / 0x7FFFFFFFF (RAND_MAX)
  • 使用random()秘密使用 arc4random),最佳精度为 1 / 0x7FFFFFFFF (RAND_MAX)

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

在数学上,通过对arc4randomarc4random_uniformrand或的单次调用实现高于 32 位的精度是不可能的random。所以我们上面的 32 位和 64 位解决方案应该是我们能做到的最好的。

回答by Héctor Sanchez

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;
}

回答by C?ur

回答by Suhit Patil

Swift 4.2

斯威夫特 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)

Swift 4.2 在标准库中包含了一个原生的、功能相当齐全的随机数 API。( Swift Evolution 提案 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.

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

回答by YannSteph

This is extension for Float random number Swift 3.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
    }
}

回答by Leslie Godwin

(float)rand() / RAND_MAX

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

上一篇仅说明“rand()”的帖子是不正确的。这是使用 rand() 的正确方法。

This will create a number between 0 -> 1

这将创建一个介于 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").

BSD 文档:

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

回答by malex

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

使用它来避免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.

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

回答by Raica Dumitru Cristian

How about this operation ((CGFloat)(rand()%100)/100)?

这个操作((CGFloat)(rand()%100)/100)怎么样?