这个随机函数有什么问题?

时间:2021-01-09 01:59:58

I give it 0 and 400 and it returns me sometimes values above 400. That doesn't make sense.

我给它0和400,它有时返回400以上的值。这没有意义。

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

that's actually a snippet I found on the net. Maybe someone can see the bug in there?

这实际上是我在网上发现的一个片段。也许有人可以看到那里的错误?

4 个解决方案

#1


The manual page for arc4random indicates that the returned value can be anywhere in the range valid for u int32 (i.e. 0 to (2**32)-1). This means you'll want to divide by 0xFFFFFFFF, instead of RAND_MAX, which I would imagine is less (it is library dependant however, so you'll have to check exactly what it is).

arc4random的手册页指示返回的值可以是对u int32有效的范围内的任何位置(即0到(2 ** 32)-1)。这意味着你想要除以0xFFFFFFFF,而不是RAND_MAX,我想这会更少(但它依赖于库,所以你必须确切地检查它是什么)。

Your function should thus become:

因此你的功能应该变成:

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

#2


  • arc4random returns a pseudo-random value from zero to (2 ^ 32 - 1)
  • arc4random返回从0到(2 ^ 32 - 1)的伪随机值

  • RAND_MAX has a default value of (2 ^ 31 - 1)
  • RAND_MAX的默认值为(2 ^ 31 - 1)

So the function is probably multiplying the (high - low) range by up to a factor of 2, for random values in the range 0 - 800.

因此,对于0到800范围内的随机值,函数可能将(高 - 低)范围乘以最多2倍。

#3


On the iPhone, RAND_MAX is 0x7fffffff (2147483647), while arc4random() will return a maximum value of 0x100000000, so (4294967296) / (2147483647) = 2..... 2 * (400-0) + 0 = 800 ! the max value the method can return

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

#4


A simpler variant would be:

一个更简单的变体是:

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

Since you're already doing a mod operation why not do it directly on the range of interest?

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

Also, why are you passing in floats (and returning floats) if you only ever pass in round numbers? Integers are more efficient.

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

#1


The manual page for arc4random indicates that the returned value can be anywhere in the range valid for u int32 (i.e. 0 to (2**32)-1). This means you'll want to divide by 0xFFFFFFFF, instead of RAND_MAX, which I would imagine is less (it is library dependant however, so you'll have to check exactly what it is).

arc4random的手册页指示返回的值可以是对u int32有效的范围内的任何位置(即0到(2 ** 32)-1)。这意味着你想要除以0xFFFFFFFF,而不是RAND_MAX,我想这会更少(但它依赖于库,所以你必须确切地检查它是什么)。

Your function should thus become:

因此你的功能应该变成:

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

#2


  • arc4random returns a pseudo-random value from zero to (2 ^ 32 - 1)
  • arc4random返回从0到(2 ^ 32 - 1)的伪随机值

  • RAND_MAX has a default value of (2 ^ 31 - 1)
  • RAND_MAX的默认值为(2 ^ 31 - 1)

So the function is probably multiplying the (high - low) range by up to a factor of 2, for random values in the range 0 - 800.

因此,对于0到800范围内的随机值,函数可能将(高 - 低)范围乘以最多2倍。

#3


On the iPhone, RAND_MAX is 0x7fffffff (2147483647), while arc4random() will return a maximum value of 0x100000000, so (4294967296) / (2147483647) = 2..... 2 * (400-0) + 0 = 800 ! the max value the method can return

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

#4


A simpler variant would be:

一个更简单的变体是:

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

Since you're already doing a mod operation why not do it directly on the range of interest?

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

Also, why are you passing in floats (and returning floats) if you only ever pass in round numbers? Integers are more efficient.

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