2

ここで奇妙な問題が発生しました。これは小さなことだと確信しています。

JSON 経由でファイルに関する情報を受け取ります (RestKit はうまく機能しています)。各ファイルのファイルサイズを coredata 経由でローカル ストアに書き込みます。

その後、私のviewcontrollersの1つで、データベース内のすべてのファイルのファイルサイズを合計する必要があります。すべてのファイルをフェッチし、勾配 (for) を使用してサイズを合計します。

問題は今、結果は常に負です!

coredata エンティティのファイルサイズは Integer 32 型です (ファイルサイズは JSON によってバイト単位で報告されます)。NSArray で fetchresult を読み取り、allPublicationsToLoad合計しようとしました。Type の NSArray 内のオブジェクトには、Type NSNumberCDPublicationの値があります。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])];

1 つの CDPublications オブジェクトの各ファイルサイズは正で正しいです。その後、すべてのファイルサイズの合計のみが負になります。現在、filesize-value が 4000 から 234.645.434.123 の間の約 240 個のオブジェクトがあります。

誰かが正しい方向にヒットしてくれませんか!? Integer 32 または NSNumber がそのような巨大な範囲を保持できないのは問題ですか?

ありがとう

MadMaxApp }

4

3 に答える 3

4

NSNumber オブジェクトは、そのような巨大な数を保持できません。負の数が格納される方法のため、結果は負になります。

負の数は2 の補数を使用して格納されます。これは、正と負の数の加算を容易にするために行われます。NSNumber が保持できる数値の範囲は 2 つに分割され、上位半分 (最上位ビットが 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ビットでは不十分な場合(あなたの場合のように)、ロング(64ビット)を使用できます。

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

これはオーバーフローに関係していると思います。非常に大きな整数は、 (32 ビット)intのサイズをオーバーフローすると、負として再解釈されます。の代わりにint使用:longLongValueintegerValue

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

これは、 2 の補数演算の使用に関連する整数オーバーフローの問題です。32 ビット整数の場合、正確に 2 32 (4,294,967,296) 通りの整数値を表現できます。2 の補数を使用する場合、最上位ビットは符号ビットとして使用され、数値の半分が非負の整数 (符号ビットが 0 の場合) を表し、残りの半分が負の数 (符号ビットが 1 の場合) を表すことができます。 )。これにより、[-2 31 , 2 31 -1] または [-2,147,483,648, 2,147,483,647]の有効範囲が得られます。

この問題を解決するには、64 ビット整数の使用を検討する必要があります。これは、使用することに関心があると思われる値の範囲でうまく機能するはずです。または、64 ビットでも十分でない場合は、iOS 用の大きな整数ライブラリを探す必要があります。

于 2012-08-28T14:51:03.107 に答える