为什么这个随机数有时会被设置为-1?

时间:2010-08-05 18:12:44

标签: iphone objective-c cocoa

一次又一次,以下是-1

int randomIndex = random() % [directionsArray count] - 1;

此类的init方法是创建directionsArray并调用srand()的位置。看起来像这样

- (id) initSprite
{
    if ( ( self = [super initSprite] ) ) {

        speed = 1;

        directionsArray = [[NSArray arrayWithObjects:STRING_CONSTANT, STRING_CONSTANT, nil] retain];
        srand(time(NULL));
        [self pickRandomDirection];


    }
    return self;
}

- (void) pickRandomDirection
{
    int randomIndex = random() % [directionsArray count] - 1; // This sometimes comes out as -1??
}

目前,我正在使用abs(randomIndex)解决这个问题,但这是作弊行为,我应该知道将来会发生什么。

6 个答案:

答案 0 :(得分:6)

因为0 - 1等于-1。

    random() % [directionsArray count] - 1;

如果random()在这里返回0怎么办?得到0%[directionsArray计数] - 1;这是-1,因为%优先于 -

也许你想要random() % ([directionsArray count] - 1);

答案 1 :(得分:5)

%优先于-1吗?如果确实如此,那么当余数为0时,1将导致负数。

答案 2 :(得分:2)

了解您的operator precedence。如有疑问,请使用括号:

int randomIndex = random() % ([directionsArray count] - 1);

答案 3 :(得分:2)

我不知道为什么没有其他人提到这一点,但解决方案(在你的情况下)实际上根本就没有减去。

正如您可能知道的那样,索引是从零开始的。余数同样从0开始,它们上升到除数减1然后循环。例如,考虑count == 3

的情况
  • 0%3 = 0
  • 1%3 = 1
  • 2%3 = 2
  • 3%3 = 0

正如Stephen Canon和Jonathan Fischoff已经告诉过你的那样,首先进行分组将导致你从这些有效索引中减去1,导致你看到的问题。

做第二次除法并不是更好:它解决了索引为-1的问题,但你仍然在切断最后一个可能的索引:

  • 0%(计数 - 1 = 2)= 0
  • 1%2 = 1
  • 2%2 = 0
  • 3%2 = 1

注意索引3永远不会出现。

仅分;减去减法。

此外,在Cocoa和Cocoa Touch中,索引通常是NSUInteger无符号整数类型,与int不同,已签名)。

答案 4 :(得分:1)

请勿使用random

改为使用arc4random

现在问题已经解决了,你从随机化表达式中减去1,在arc4random % len返回0的情况下,你要从中减去1,这是-1

答案 5 :(得分:1)

我推荐arc4random。它似乎是SDK中最容易使用和最好的rnd。

arc4random() % [directionsArray count];