我正在创建一个随机数并将其存储在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返回)并确保它们只是正数?
答案 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)
中,您应该注意^
是排他性的,或者不是取幂。