1

我正在创建一个随机数并将其存储在 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 返回的)并确保它们只是正数?

4

2 回答 2

0

利用

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

我从来没有得到任何负数。arc4random_uniform(x)总是返回一个介于 0 和 x 之间的数字,并且从中生成的 NSNumber 的 stringvalue 是正确的。

编辑:用 exp2(32) 替换 exp2(31)

于 2013-03-01T10:32:55.360 回答
0

您在评论中说索引作为“整数 32”属性存储在核心数据实体中,我认为这就是问题所在。

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

对于“整数 32”属性,Core Data 使用(有符号)整数作为属性,当你设置一个值时,它只是被强制转换或截断为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.

如果您需要 range 中的无符号整数0 .. 2^32-1,那么您可以(就像您已经做过的那样)使用unsignedIntValue

unsigned x = [val unsignedIntValue];

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

评论:

  • 我相当确定这不是arc4random_uniform.
  • 在您的第一个代码示例arc4random_uniform(2^32-1)中,您应该注意这^是异或,而不是求幂。
于 2013-03-01T12:48:36.980 回答