To musi być łatwe, ale jak zsumować dwa NSNumber
? Jest jak:
[one floatValue] + [two floatValue]
czy istnieje lepszy sposób?
źródło
To musi być łatwe, ale jak zsumować dwa NSNumber
? Jest jak:
[one floatValue] + [two floatValue]
czy istnieje lepszy sposób?
Nie ma lepszego sposobu, ale naprawdę nie powinieneś tego robić, jeśli możesz tego uniknąć. NSNumber
istnieje 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:
...
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 [].
źródło
NSDecimalNumber
s, jak przekonwertowaćNSDecimalNumber
wynik z powrotem naNSNumber
? (To pytanie dotyczy dodawania dwóchNSNumber
s, a nie dodawania dwóchNSDecimalNumber
.)@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
NSNumber
instancji, które przechowują wartości całkowite. Jeśli chcesz dodać dwaNSNumber
, które przechowują wartości zmiennoprzecinkowe, wykonaj następujące czynności:NSNumber *sum = @([first floatValue] + [second floatValue]);
źródło
int
lublong
czy jest to wielki brattypedef
„edNSInteger
doNSNumber
obiektów .integerValue
obcinafloat
. Jak można głosować pozytywnie na tę odpowiedź?integerValue
jeś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 :
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)
źródło
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]); }
źródło
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
źródło