Swift随机浮点 fatal error : no uniform distribution on an infinite range

标签 swift random floating-point

我正在尝试生成一个完全随机的float值,这应该很容易。但是,它不起作用,从外观上看,也许我是第一个遇到此错误的人?我当然似乎找不到任何有关它的先前帖子。

这段代码:

let min = -Float.greatestFiniteMagnitude
let max = +Float.greatestFiniteMagnitude
let range = min...max
let random = Float.random(in: range)

一直工作到最后一行,该行失败,产生Swift/FloatingPointRandom.swift:162: Fatal error: There is nouniform distribution on anInfinite range

但是,范围不应该是无限的。检查 Playground 中的最小值和最大值或范围本身表明,边界是 -3.402823e+383.402823e+38,两者都不是无限的。

这是怎么回事?有没有一种正确的方法可以做到这一点,我错过了?除此之外,对于这样一个简单的任务来说,这似乎非常复杂:

let min = Float(0)
let max = Float.greatestFiniteMagnitude
let range = min...max
let signs : [Float] = [-1, 1]
let random = Float.random(in: range) * signs.randomElement()!

最佳答案

这是当前浮点值随机数生成实现的限制 - 如果您查看 stdlib/public/core/FloatingPointRandom.swift:156 (就在错误消息指向的地方),您可以看到此限制来自何处:

let delta = range.upperBound - range.lowerBound
//  TODO: this still isn't quite right, because the computation of delta
//  can overflow (e.g. if .upperBound = .maximumFiniteMagnitude and
//  .lowerBound = -.upperBound); this should be re-written with an
//  algorithm that handles that case correctly, but this precondition
//  is an acceptable short-term fix.
_precondition(
  delta.isFinite,
  "There is no uniform distribution on an infinite range"
)

如果边界无效,代码会尝试阻止生成随机数,但不能充分处理溢出。有一个GitHub issue tracking this bug ,但它似乎已经存在了一段时间 - 尽管有评论指出这将在 Swift 5 中修复,但该修复尚未引入。

可能值得对这个问题发表评论,或者在 Swift forums 上提出这个问题。 ,可以解决该问题的工程师可以在其中看到这一点。


与此同时,您提出的解决方案应该让您足够接近,对于“足够接近”的某些定义:您将获得所需范围内的随机数,尽管浮点精度的限制可能会影响你得到的数字的精确分布。根据您的用例,这可能并不重要,但在不了解更多信息的情况下,在引入完整修复之前,这可能对您有用,也可能不起作用。

您还可以尝试生成一个比 [-1, 1] 范围大得多的随机数,并按较小的比例对其进行缩放,这可能会让您获得更准确的值分布.

关于Swift随机浮点 fatal error : no uniform distribution on an infinite range,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/75467199/

相关文章:

ios - 添加手势识别器以允许在 Swift 中的 MapView 上水平滑动

arrays - 如何在 Swift 中打乱数组?

iphone - 如何随机放置 UIButton 和值

python - 如何在python中转换 float ?

c# - float.Parse 返回不正确的值

arrays - 在二维数组 NxN Swift 上创建、随机填充和搜索元素

swift - 约束不会快速更新

random - 在最小值、最大值之间生成加密随机整数

javascript - 防止随机操作在 Javascript 中返回相同的值两次

java - Java应用程序拒绝将输出显示为 float 。尝试过强制转换,乘以1.0,加上0.0,没有任何作用