ios取两个数之间的随机小数_关于ios:生成0到1之间的随机浮点数

本文介绍了如何在iOS中生成0到1(包括0,不包括1)之间的随机浮点数,主要讨论了arc4random()函数的使用,并提供了不同精度的随机数生成方法,包括使用drand48()以及Swift的解决方案。
摘要由CSDN通过智能技术生成

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

不是重复项,这似乎是与浮点数明确相关的唯一问题。

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

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

这里有更多细节。

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

谢谢。我见过的最直接的答案。我将阅读您的链接,并获取有关此信息的其他详细信息。再次感谢。

奇怪的是必须手动定义ARC4RANDOM_MAX,但是0x100000000是4294967296,也就是ULONG_MAX + 1。无论如何,arc4random() s max是ULONG_MAX的记录在哪里?

@bobobobo,来自此处:developer.apple.com/library/mac/#documentation/Darwin/Reference/ arc4random()函数返回0至(2 ** 32)-1范围内的伪随机数

@bobobobo,尽管我同意为这种情况定义常量看起来不太好

实际上,该值应为0xFFFFFFFF,(2 ** 32)-1 == 0x100000000-0x1 == 0xFFFFFFFF == UINT32_MAX,目前由Jrg Bhmann在链接上声明。

@Vladimir,ARC4RANDOM_MAX是什么类型?我想将其定义为变量。

@IulianOnofrei,您可以将其声明为unsigned long。

不能保证以这种方式生成的值是均匀分布的!

@Josejulio,你说得对,我用UINT32_MAX做了一个单独的答案:stackoverflow.com/a/34765674/1033581

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

这应该是最好的答案。

您可能只需要更新一点答案,我在NSHipster上读到drand48需要使用种子进行一次初始化。 Apple文档还建议应将其初始化。

它无需初始化即可为我工作

需要种子,因为它为该随机生成器提供了计算的起点。没有它,随机序列在应用程序启动时将始终是相同的。

这是最好的答案。

对于double,此答案不是最佳精度答案。有关如何获得最佳精度的信息,请参见stackoverflow.com/a/34765674/1033581。

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

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

32位精度(对于Float最佳)

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

对象:

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

迅速:

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

最适合:

Float(或Float32)的尾数精度为24位

48位精度(已淘汰)

使用drand48(在后台使用arc4random_buf)很容易实现48位精度。但是请注意,drand48的缺陷在于种子的要求,并且由于对次双尾数的所有52位随机化都不理想。

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

迅速:

// 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 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位

Float80的尾数有效位数为64位

笔记

与其他方法的比较

范围不包括边界之一(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即可获得优于32位的精度。因此,我们上面的32位和64位解决方案应该是我们可以达到的最佳解决方案。

Float80在真正的iOS设备上不可用(仅在模拟器上可用)。

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

float randomFloat(float Min, float Max){

return ((arc4random()%RAND_MAX)/(RAND_MAX*1.0))*(Max-Min)+Min;

}

无关的模数运算。使用Min+(Max-Min)*((float)arc4random())ULONG_MAX代替。 (float)强制转换只是妄想症。

@bobobobo虽然我同意无关紧要的模数,但我建议用UINT32_MAX(始终为4294967295)除以ULONG_MAX(64位为18446744073709551615)。

迅捷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)

文件:

random(in range: ClosedRange)

random(in range: Range)

random(in range: ClosedRange)

random(in range: Range)

random(in range: ClosedRange)

random(in range: Range)

斯威夫特4.2

Swift 4.2在标准库中包含了一个本机且功能相当齐全的随机数API。 (快速演进建议SE-0202)

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

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

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

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

}

}

@C?ur谢谢你我改变了

(float)rand() / RAND_MAX

以前仅指出" rand()"的帖子是不正确的。

这是使用rand()的正确方法。

这将在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").

使用它来避免arc4random()的上限问题

u_int32_t upper_bound = 1000000;

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

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

这有一个基本的范围问题。当您将upper_bound设置为10时,arc4random_uniform将返回从0到9的值,最终结果将从0.0000到0.9000,这很容易注意到。您应改为除以upper_bound-1。但是,由于upper_bound导致的精度仍然会任意降低,因此应将upper_bound增大为UINT32_MAX。使用arc4random()*1.0 UINT32_MAX而不是arc4random_uniform(UINT32_MAX)*1.0 (UINT32_MAX-1)可以获得更高的精度。

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

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

srand48(time(0));      // pseudo-random number initializer.

double r = drand48();

arc4random最大值为0xFFFFFFFF

谢谢@C?ur ..max val 0xFFFFFFFF我当时不知道

您的解决方案也与Jovan Stankovic的回答相同。

哦,我没有看到@C?ur

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

模偏差和精度偏差。对于同一个想法,莱斯利·戈德温斯(Leslie Godwins)的回答更好。

默认情况下会产生一个介于0和1之间的随机数(浮点数)。

这为我产生了一个随机整数。

rand()在iOS上似乎不存在,并且如果存在,它将生成一个整数,就像在其他* NIX上一样。

@JoshCaswell rand()是C的一部分,而C又是Objective-C(在iOS编程中使用)的一部分。像rand()这样的C函数在iOS上绝对存在,但首选arc4random()。

float x = arc4random() % 11 * 0.1;

在0和1之间产生一个随机浮点数。

更多信息在这里

注意:仅给出11个离散值:0.0、0.1、0.2,...,1.0

是的,模运算将arc4random()的结果减少到0到10之间,然后将其除以10。这个答案对于一般用途来说确实是不好的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值