2

我在这里遇到了一个奇怪的问题,我敢肯定这只是小问题。

我通过 JSON 接收有关文件的信息(RestKit 做得很好)。我通过 coredata 将每个文件的文件大小写入本地存储。

之后在我的一个视图控制器中,我需要总结数据库中所有文件的文件大小。我获取所有文件,然后通过一个斜率(for)来总结大小。

问题是现在,结果总是否定的!

coredata 实体文件大小的类型为 Integer 32(文件大小由 JSON 以字节为单位报告)。我在 NSArray 中读取了 fetchresult,allPublicationsToLoad然后尝试总结。Type 的 NSArray 中的 ObjectsCDPublication有一个 NSNumber 类型的值filesize

for(int n = 0; n < [allPublicationsToLoad count]; n = n + 1)
{
    CDPublication* thePub = [allPublicationsToLoad objectAtIndex:n];
    allPublicationsSize = allPublicationsSize + [[thePub filesize] integerValue];
    sum = [NSNumber numberWithFloat:([sum floatValue] + [[thePub filesize] floatValue])];

单个 CDPublications 对象的每个单个文件大小都是正数且正确的。之后只有所有文件大小的总和为负。现在大约有 240 个对象,文件大小值介于 4000 和 234.645.434.123 之间。

有人可以给我一个正确的方向吗!?是 Integer 32 或 NSNumber 不能容纳这么大的范围的问题吗?

谢谢

疯狂的应用程序}

4

3 回答 3

4

NSNumber 对象不能容纳这么大的数字。由于负数的存储方式,结果是负数。

负数使用二进制补码存储,这样做是为了使正数和负数的加法更容易。NSNumber 可以容纳的数字范围分为两部分,最高一半(最高位等于 1 的 int 值)被认为是负数,最低一半(最高位等于 0)是正常的正数。现在,如果您添加足够大的数字,结果将位于最高一半,因此被解释为负数。这是 4 位整数情况的说明(32 的工作原理完全相同,但要键入的 0 和 1 会多得多;))

使用 4 位,您可以表示以下有符号整数范围:

0000 (=0)
0001 (=1)
0010 (=2)
... 
0111 (=7)

1000 (=-8)
1001 (=-7)
...
1111 (=-1)

在这种情况下,您可以表示的最大正整数是 7。例如,如果您添加 5 和 4,您将得到:

0101 + 0100 = 1001

当您表示这样的有符号整数时,1001 等于 -7(而不是 9,正如您所期望的那样)。这就是您正在观察的效果,但规模更大(32 位)

在这种情况下,获得正确结果的唯一选择是增加用于表示整数的位数,这样结果就不会在位组合的负数范围内。因此,如果 32 位不够(如您的情况),您可以使用 long(64 位)。

[myNumber longLongValue];
于 2012-08-28T14:47:43.037 回答
3

我认为这与int溢出有关:非常大的整数在溢出int(32 位)的大小时会被重新解释为负数。使用longLongValue代替integerValue

long long allPublicationsSize = 0;
for(int n = 0; n < [allPublicationsToLoad count]; n++) {
    CDPublication* thePub = [allPublicationsToLoad objectAtIndex:n];
    allPublicationsSize += [[thePub filesize] longLongValue];
}
于 2012-08-28T14:48:04.160 回答
2

这是与使用二进制补码算法相关的整数溢出问题。对于一个 32 位整数,恰好有 2 32 (4,294,967,296) 个可以表示的可能整数值。使用二进制补码时,最高有效位用作符号位,它允许一半的数字表示非负整数(当符号位为 0 时),另一半表示负数(当符号位为 1 时) )。这给出了 [-2 31 , 2 31 -1] 或 [-2,147,483,648, 2,147,483,647] 的有效范围。

要为您的情况克服这个问题,您应该考虑使用 64 位整数。这应该适用于您似乎有兴趣使用的值范围。或者,如果 64 位还不够,您应该寻找适用于 iOS 的大整数库。

于 2012-08-28T14:51:03.107 回答