【问题标题】:What's wrong with this randomize function?这个随机化函数有什么问题?
【发布时间】:2009-07-15 12:29:33
【问题描述】:

我给它 0 和 400,它有时会返回超过 400 的值。这没有意义。

- (float)randomValueBetween:(float)low andValue:(float)high {
    return (((float) arc4random() / RAND_MAX) * (high - low)) + low;
}

这实际上是我在网上找到的一个sn-p。也许有人可以看到那里的错误?

【问题讨论】:

  • 只是为了迂腐,这个错误与 UIKit、iPhone 或(几乎没有)Objective-C 没有太大关系;)

标签: iphone objective-c cocoa-touch uikit


【解决方案1】:

manual page for arc4random 表示返回值可以是u int32 有效范围内的任何位置(即0 to (2**32)-1)。这意味着您需要除以0xFFFFFFFF,而不是RAND_MAX,我想它会更少(但是它依赖于库,因此您必须检查它到底是什么)。

因此你的函数应该变成:

- (float)randomValueBetween:(float)low andValue:(float)high {
    return (((float) arc4random() / 0xFFFFFFFFu) * (high - low)) + low;
}

【讨论】:

  • 我会使用 UINT32_MAX 而不是显式值。
  • 是啊,看来他真的很生气0xffffffffu
【解决方案2】:
  • arc4random 返回一个从零到 (2 ^ 32 - 1) 的伪随机值
  • RAND_MAX 的默认值为 (2 ^ 31 - 1)

因此,对于0 - 800 范围内的随机值,该函数可能会将(high - low) 范围乘以2 的系数。

【讨论】:

    【解决方案3】:

    在 iPhone 上,RAND_MAX 为 0x7fffffff (2147483647),而 arc4random() 将返回最大值 0x100000000,因此 (4294967296) / (2147483647) = 2..... 2 * (400-0) + 0 = 800 !方法可以返回的最大值

    【讨论】:

      【解决方案4】:

      一个更简单的变体是:

      - (float)randomValueBetween:(float)low andValue:(float)high {
          return (arc4random() % * (high - low)) + low;
      }
      

      既然你已经在做一个 mod 操作,为什么不直接在感兴趣的范围内做呢?

      另外,如果你只传递整数,为什么还要传递浮点数(并返回浮点数)?整数更有效。

      【讨论】:

      • 如果highlow 之间的差异是浮点数,那么您需要调用fmodf()
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-03-26
      • 2014-06-29
      • 2011-02-13
      • 2011-04-24
      • 2011-08-26
      • 1970-01-01
      • 2023-03-23
      相关资源
      最近更新 更多