iOS calculando la sum de los files siempre negativos

Tengo un problema extraño aquí, y estoy seguro de que es solo algo pequeño.

Recibo información sobre files a través de JSON (RestKit está haciendo un buen trabajo). Escribo el tamaño de file de cada file a través de conetworkingata a una tienda local.

Luego, dentro de uno de mis controlleres de vista, necesito resumir los files de todos los files en la database. Recojo todos los files y luego paso por una pendiente (para) para sumr el tamaño.

¡El problema es ahora, el resultado siempre es negativo!

El tamaño de file de la entidad de conetworkingata es del tipo Entero 32 (JSON informa el tamaño de file en bytes). Leí el file fetchresult en un NSArray allPublicationsToLoad y luego trato de resumir. Los objects en el NSArray de Type CDPublication tienen un filesize de filesize de valor de Type NSNumber:

 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])]; 

Cada tamaño de file individual de los objects CDP de publicaciones individuales es positivo y correcto. Solo la sum de todos los files es negativo después. Actualmente hay alnetworkingedor de 240 objects con valores de tamaño de file entre 4000 y 234.645.434.123.

¿Alguien puede darme un golpe en la dirección correcta? ¿El problema es que Integer 32 o NSNumber no pueden contener un range tan grande?

Gracias

MadMaxApp}

    El object NSNumber no puede contener un número tan grande. Debido a la forma en que se almacenan los numbers negativos, el resultado es negativo.

    Los numbers negativos se almacenan usando el complemento de dos , esto se hace para facilitar la adición de numbers positivos y negativos. El range de numbers que NSN puede contener se divide en dos, la mitad más alta (los valores int para los cuales el bit de order más elevado es igual a 1) se considera negativa, la mitad más baja (donde el bit de order más elevado es igual a 0) son los numbers positivos normales. Ahora, si agrega numbers suficientemente grandes, el resultado estará en la mitad más alta y, por lo tanto, se interpretará como un número negativo. Aquí hay una ilustración para la situación entera de 4 bits (32 funciona exactamente igual, pero habría mucho más 0 y 1 para escribir;))

    Con 4 bits puede representar este range de integers con signo:

     0000 (=0) 0001 (=1) 0010 (=2) ... 0111 (=7) 1000 (=-8) 1001 (=-7) ... 1111 (=-1) 

    El integer positivo máximo que puede representar es 7 en este caso. Si agrega 5 y 4, por ejemplo, obtendrá:

     0101 + 0100 = 1001 

    1001 es igual a -7 cuando representa integers con signo como este (y no 9, como era de esperar). Ese es el efecto que estás observando, pero a una escala mucho mayor (32 bits)

    Su única opción para get resultados correctos en este caso es boost la cantidad de bits utilizados para representar sus numbers integers, por lo que el resultado no estará en el range de numbers negativos de las combinaciones de bits. Entonces, si 32 bits no son suficientes (como en su caso), puede usar un largo (64 bits).

     [myNumber longLongValue]; 

    Creo que esto tiene que ver con el desbordamiento de int : integers muy grandes se reinterpretan como negativos cuando desbordan el tamaño de int (32 bits). Use longLongValue lugar de integerValue :

     long long allPublicationsSize = 0; for(int n = 0; n < [allPublicationsToLoad count]; n++) { CDPublication* thePub = [allPublicationsToLoad objectAtIndex:n]; allPublicationsSize += [[thePub filesize] longLongValue]; } 

    Este es un problema de desbordamiento integer asociado con el uso de la aritmética del complemento de dos . Para un integer de 32 bits, existen exactamente 2 32 (4,294,967,296) valores integers posibles que se pueden express. Cuando se usa el complemento de dos, el bit más significativo se usa como un bit de signo que permite que la mitad de los numbers represente numbers integers no negativos (cuando el bit de signo es 0) y la otra mitad para representar numbers negativos (cuando el bit de signo es 1 ) Esto da un range efectivo de [-2 31 , 2 31 -1] o [-2,147,483,648, 2,147,483,647].

    Para superar este problema en su caso, debe considerar utilizar un integer de 64 bits. Esto debería funcionar bien para el range de valores que pareces estar interesado en usar. Alternativamente, si incluso 64 bits no es suficiente, debería search bibliotecas grandes enteras para iOS.