NSNumber中的arc4random给出负值?

时间:2013-03-01 10:04:53

标签: objective-c nsnumber arc4random

我正在创建一个随机数并将其存储在NSNumber对象中,如下所示:

NSNumber *index = [NSNumber numberWithUnsignedInt:arc4random_uniform(2^32-1)];

我也尝试过:

NSNumber *index = [NSNumber numberWithUnsignedInt:arc4random_uniform(4294967295)];
NSNumber *index = @(arc4random_uniform(4294967295));

在某些时候,我也会像这样分配数字1:

NSNumber *index = @(1);

这应该只给我正数。

稍后,我打印出这样的数字:

NSString *string = [NSString stringWithFormat:@"%@", index];

这给了我一些随机数的负值,1给我打印为1.所以我可能会这样做:

NSString *string = [NSString stringWithFormat:@"%u", index.unsignedIntValue];

我只会得到正数 - 我这样做 - 但现在1突然被打印为一些大的正数,也是。

这里发生了什么?如何在NSNmber中正确存储u_int32(arc4random返回)并确保它们只是正数?

2 个答案:

答案 0 :(得分:0)

使用

NSNumber *index = [NSNumber numberWithUnsignedInt:arc4random_uniform(exp2(32)-1)];

我从来没有得到任何负数。 arc4random_uniform(x)始终返回0到x之间的数字,并且从中生成的NSNumber的字符串值是正确的。

编辑:将exp2(31)替换为exp2(32)

答案 1 :(得分:0)

您在评论中说,索引作为“整数32”属性存储在Core Data实体中,我认为这是问题的来源。

Core Data为托管对象类的所有属性(和关系)动态生成getter和setter方法。这些访问器方法不同于由实例变量备份的“常用”@synthesized访问器方法。

对于“整数32”属性,核心数据对属性使用(带符号)整数,当您设置值时,它只是强制转换或截断为int。例如:

e.index = [NSNumber numberWithUnsignedInt:0xFFFFFFF0U];
// This would give the same result:
// e.index = [NSNumber numberWithLongLong:0x1234FFFFFFF0LL];
NSNumber *val = e.index;
NSLog(@"value=%@, type=%s", val, [val objCType]);
// Output: value=-16, type=i

输出type=i表示该值包含int

如果您需要0 .. 2^32-1范围内的无符号整数,那么您可以(正如您所做的那样)使用unsignedIntValue

unsigned x = [val unsignedIntValue];

或将属性存储为“Integer 64”。

说明:

  • 我很确定这不是arc4random_uniform
  • 的问题
  • 在您的第一个代码示例arc4random_uniform(2^32-1)中,您应该注意^是排他性的,或者不是取幂。
相关问题