To musi być łatwe, ale jak zsumować dwa NSNumber? Jest jak:
[one floatValue] + [two floatValue]
czy istnieje lepszy sposób?
Odpowiedzi:
Nie ma lepszego sposobu, ale naprawdę nie powinieneś tego robić, jeśli możesz tego uniknąć. NSNumberistnieje jako opakowanie dla liczb skalarnych, dzięki czemu można je przechowywać w kolekcjach i przekazywać je polimorficznie z innymi NSObjects. Nie są tak naprawdę używane do przechowywania liczb w rzeczywistej matematyce. Jeśli wykonujesz na nich obliczenia matematyczne, jest to znacznie wolniejsze niż wykonywanie operacji na samych skalarach, dlatego prawdopodobnie nie ma na to wygodnych metod.
Na przykład:
NSNumber *sum = [NSNumber numberWithFloat:([one floatValue] + [two floatValue])];
Wydmuchuje co najmniej 21 instrukcji dotyczących wysyłek wiadomości i ile kodu zajmą metody, aby rozpakować i zmienić wartości (prawdopodobnie kilkaset), aby wykonać jedną instrukcję matematyczną.
Więc jeśli chcesz przechowywać liczby w dyktach, użyj znaku an NSNumber, jeśli chcesz przekazać do funkcji coś, co może być liczbą lub ciągiem znaków, użyj znaku NSNumber, ale jeśli chcesz po prostu używać matematyki trzymaj się skalarnych typów C.
NSDecimalNumber (podklasa NSNumber ) zawiera wszystkie gadżety, których szukasz:
– decimalNumberByAdding:
– decimalNumberBySubtracting:
– decimalNumberByMultiplyingBy:
– decimalNumberByDividingBy:
– decimalNumberByRaisingToPower:
...
Jeśli interesuje Cię wydajność obliczeniowa, przekonwertuj na tablicę std :: vector w C ++ lub podobną.
Teraz już nigdy nie używam C-Arrays; zbyt łatwo ulega awarii przy użyciu niewłaściwego indeksu lub wskaźnika. I bardzo żmudne parowanie każdego nowego [] z delete [].
NSDecimalNumbers, jak przekonwertować NSDecimalNumberwynik z powrotem na NSNumber? (To pytanie dotyczy dodawania dwóch NSNumbers, a nie dodawania dwóch NSDecimalNumber.)
@interface NSDecimalNumber : NSNumber
Możesz użyć
NSNumber *sum = @([first integerValue] + [second integerValue]);
Edycja: jak zaobserwował Ohho , ten przykład służy do dodawania dwóch NSNumberinstancji, które przechowują wartości całkowite. Jeśli chcesz dodać dwa NSNumber, które przechowują wartości zmiennoprzecinkowe, wykonaj następujące czynności:
NSNumber *sum = @([first floatValue] + [second floatValue]);
intlub longczy jest to wielki brat typedef„ed NSIntegerdo NSNumber obiektów .
integerValueobcina float. Jak można głosować pozytywnie na tę odpowiedź?
integerValuejeśli chcesz zachować dziesiętną część liczb?
Obecna, najczęściej wybierana odpowiedź doprowadzi do trudnych do zdiagnozowania błędów i utraty precyzji z powodu użycia pływaków. Jeśli wykonujesz operacje liczbowe na wartościach NSNumber, powinieneś najpierw przekonwertować na NSDecimalNumber i zamiast tego wykonać operacje na tych obiektach.
Z dokumentacji :
NSDecimalNumber, niezmienna podklasa NSNumber, zapewnia zorientowaną obiektowo otokę do wykonywania arytmetyki na podstawie 10. Instancja może reprezentować dowolną liczbę, którą można wyrazić jako mantysa x 10 ^ wykładnik, gdzie mantysa jest dziesiętną liczbą całkowitą o długości do 38 cyfr, a wykładnikiem jest liczbą całkowitą od –128 do 127.
Dlatego powinieneś przekonwertować swoje wystąpienia NSNumber na NSDecimalNumbers w drodze [NSNumber decimalValue], wykonać dowolną arytmetykę, a następnie przypisać z powrotem do NSNumber, kiedy skończysz.
W celu C:
NSDecimalNumber *a = [NSDecimalNumber decimalNumberWithDecimal:one.decimalValue]
NSDecimalNumber *b = [NSDecimalNumber decimalNumberWithDecimal:two.decimalValue]
NSNumber *result = [a decimalNumberByAdding:b]
W Swift 3:
let a = NSDecimalNumber(decimal: one.decimalValue)
let b = NSDecimalNumber(decimal: two.decimalValue)
let result: NSNumber = a.adding(b)
Dlaczego nie używać 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"
Możesz również zbudować NSExpression, którego można ponownie użyć do oceny z różnymi argumentami, na przykład:
NSExpression *expr = [NSExpression expressionWithFormat: @"(X+Y)"];
NSDictionary *parameters = [NSDictionary dictionaryWithObjectsAndKeys:x, @"X", y, @"Y", nil];
NSLog(@"%@", [expr expressionValueWithObject:parameters context:nil]);
Na przykład możemy zapętlić obliczenie tego samego przeanalizowanego wyrażenia, za każdym razem z inną wartością „Y”:
for (float f=20; f<30; f+=2.0) {
NSDictionary *parameters = [NSDictionary dictionaryWithObjectsAndKeys:x, @"X", @(f), @"Y", nil];
NSLog(@"%@", [expr expressionValueWithObject:parameters context:nil]);
}
W Swift możesz uzyskać tę funkcjonalność, korzystając z biblioteki Bolt_Swift https://github.com/williamFalcon/Bolt_Swift .
Przykład:
var num1 = NSNumber(integer: 20)
var num2 = NSNumber(integer: 25)
print(num1+num2) //prints 45