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
Generate a random float between 0 and 1
提问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
(orFloat32
) which has a significand precision of 24 bits for its mantissa
- a
Float
(orFloat32
) 其尾数的有效位精度为 24 位
48 bits precision (discouraged)
48 位精度(不鼓励)
It's easy to achieve 48 bits precision with drand48
(which uses arc4random_buf
under 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 Double
and Float80
)
64 位精度(最适合Double
和Float80
)
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
(orFloat64
) which has a significand precision of 52 bits for its mantissa - a
Float80
which has a significand precision of 64 bits for its mantissa
- a
Double
(orFloat64
) 其尾数的有效位精度为 52 位 - a
Float80
其尾数的有效位精度为 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
, rand
or random
. So our above 32 bits and 64 bits solutions should be the best we can achieve.
在数学上,通过对arc4random
、arc4random_uniform
、rand
或的单次调用实现高于 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
Swift 4.2+
斯威夫特 4.2+
Swift 4.2 adds native support for a random value in a Range:
Swift 4.2 添加了对 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:
文件:
回答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)
怎么样?