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. NSNumber
existe 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 [].
NSDecimalNumber
s, ¿cómo convertir el NSDecimalNumber
resultado a NSNumber
? (Esta pregunta trata sobre la suma de dos NSNumber
s, no la suma de dos NSDecimalNumber
s.)
@interface NSDecimalNumber : NSNumber
Puedes usar
NSNumber *sum = @([first integerValue] + [second integerValue]);
Editar: como lo observó ohho , este ejemplo es para sumar dos NSNumber
instancias que contienen valores enteros. Si desea sumar dos NSNumber
que contienen valores de punto flotante, debe hacer lo siguiente:
NSNumber *sum = @([first floatValue] + [second floatValue]);
int
o long
, o que es hermano mayor typedef
ed' NSInteger
en NSNumber
los objetos .
integerValue
trunca float
. ¿Cómo se puede mejorar esta respuesta?
integerValue
si 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