Ahora bien, esto debe ser fácil, pero ¿cómo se pueden sumar dos NSNumber? Es como:
[one floatValue] + [two floatValue]
o existe una mejor manera?
Respuestas:
Realmente no hay una mejor manera, pero realmente no debería hacer esto si puede evitarlo. NSNumberexiste como contenedor de números escalares para que pueda almacenarlos en colecciones y pasarlos polimórficamente con otros NSObjects. En realidad, no se utilizan para almacenar números en matemáticas reales. Si hace cálculos matemáticos con ellos, es mucho más lento que realizar la operación solo con los escalares, por lo que probablemente no hay métodos convenientes para ello.
Por ejemplo:
NSNumber *sum = [NSNumber numberWithFloat:([one floatValue] + [two floatValue])];
Está soplando un mínimo de 21 instrucciones en los envíos de mensajes, y sin importar la cantidad de código que necesiten los métodos para desempaquetar y volver a empaquetar los valores (probablemente unos cientos) para hacer 1 instrucción de matemáticas.
Entonces, si necesita almacenar números en dictados, use an NSNumber, si necesita pasar algo que podría ser un número o una cadena en una función, use an NSNumber, pero si solo desea hacer matemáticas con tipos escalares C.
NSDecimalNumber (subclase de NSNumber ) tiene todas las ventajas que está buscando:
– decimalNumberByAdding:
– decimalNumberBySubtracting:
– decimalNumberByMultiplyingBy:
– decimalNumberByDividingBy:
– decimalNumberByRaisingToPower:
...
Si el rendimiento informático es de interés, conviértalo a C ++ array std :: vector o similar.
Ahora nunca más uso C-Arrays; es muy fácil fallar usando un índice o puntero incorrecto. Y muy tedioso emparejar cada nuevo [] con eliminar [].
NSDecimalNumbers, ¿cómo convertir el NSDecimalNumberresultado a NSNumber? (Esta pregunta trata sobre la suma de dos NSNumbers, no la suma de dos NSDecimalNumbers.)
@interface NSDecimalNumber : NSNumber
Puedes usar
NSNumber *sum = @([first integerValue] + [second integerValue]);
Editar: como lo observó ohho , este ejemplo es para sumar dos NSNumberinstancias que contienen valores enteros. Si desea sumar dos NSNumberque contienen valores de punto flotante, debe hacer lo siguiente:
NSNumber *sum = @([first floatValue] + [second floatValue]);
into long, o que es hermano mayor typedefed' NSIntegeren NSNumber los objetos .
integerValuetrunca float. ¿Cómo se puede mejorar esta respuesta?
integerValuesi quieres conservar la parte decimal de los números?
La respuesta actual más votada conducirá a errores difíciles de diagnosticar y pérdida de precisión debido al uso de flotadores. Si está realizando operaciones numéricas en valores NSNumber, primero debe convertir a NSDecimalNumber y realizar operaciones con esos objetos.
De la documentación :
NSDecimalNumber, una subclase inmutable de NSNumber, proporciona un contenedor orientado a objetos para realizar operaciones aritméticas en base 10. Una instancia puede representar cualquier número que se pueda expresar como mantisa x 10 ^ exponente donde mantisa es un número entero decimal de hasta 38 dígitos y el exponente es un número entero de –128 a 127.
Por lo tanto, debe convertir sus instancias de NSNumber a NSDecimalNumbers [NSNumber decimalValue], realizar la aritmética que desee y luego volver a asignar un NSNumber cuando haya terminado.
En Objective-C:
NSDecimalNumber *a = [NSDecimalNumber decimalNumberWithDecimal:one.decimalValue]
NSDecimalNumber *b = [NSDecimalNumber decimalNumberWithDecimal:two.decimalValue]
NSNumber *result = [a decimalNumberByAdding:b]
En Swift 3:
let a = NSDecimalNumber(decimal: one.decimalValue)
let b = NSDecimalNumber(decimal: two.decimalValue)
let result: NSNumber = a.adding(b)
¿Por qué no usar NSxEpression?
NSNumber *x = @(4.5), *y = @(-2);
NSExpression *ex = [NSExpression expressionWithFormat:@"(%@ + %@)", x, y];
NSNumber *result = [ex expressionValueWithObject:nil context:nil];
NSLog(@"%@",result); // will print out "2.5"
También puede crear una NSExpression que se puede reutilizar para evaluar con diferentes argumentos, como este:
NSExpression *expr = [NSExpression expressionWithFormat: @"(X+Y)"];
NSDictionary *parameters = [NSDictionary dictionaryWithObjectsAndKeys:x, @"X", y, @"Y", nil];
NSLog(@"%@", [expr expressionValueWithObject:parameters context:nil]);
Por ejemplo, podemos evaluar en bucle la misma expresión analizada, cada vez con un valor de "Y" diferente:
for (float f=20; f<30; f+=2.0) {
NSDictionary *parameters = [NSDictionary dictionaryWithObjectsAndKeys:x, @"X", @(f), @"Y", nil];
NSLog(@"%@", [expr expressionValueWithObject:parameters context:nil]);
}
En Swift, puede obtener esta funcionalidad utilizando la biblioteca Bolt_Swift https://github.com/williamFalcon/Bolt_Swift .
Ejemplo:
var num1 = NSNumber(integer: 20)
var num2 = NSNumber(integer: 25)
print(num1+num2) //prints 45