Тепер це має бути легко, але як можна підсумувати два NSNumber
? Це як:
[one floatValue] + [two floatValue]
чи існує кращий спосіб?
Відповіді:
Насправді не є кращого способу, але ви дійсно не повинні робити цього, якщо зможете цього уникнути. NSNumber
існує як обгортка для скалярних чисел, тому ви можете зберігати їх у колекціях і передавати поліморфно разом з іншими NSObjects
. Вони насправді не використовуються для зберігання чисел у реальній математиці. Якщо ви робите математику на них, це набагато повільніше, ніж виконання операції лише на скалярах, імовірно, тому для цього не існує зручних методів.
Наприклад:
NSNumber *sum = [NSNumber numberWithFloat:([one floatValue] + [two floatValue])];
Здійснює мінімум 21 інструкцію щодо відправлення повідомлень, і скільки б методів не вимагалося для розпакування та перепакування значень (можливо, кілька сотень), щоб зробити 1 інструкцію на суму математики.
Отже, якщо вам потрібно зберігати числа в диктах, використовуйте NSNumber
, якщо вам потрібно передати щось, що може бути числом або рядком, у функцію, використовуйте NSNumber
, але якщо ви просто хочете зробити математичну палицю зі скалярними типами C.
NSDecimalNumber (підклас NSNumber ) містить усі потрібні вам смаколики:
– decimalNumberByAdding:
– decimalNumberBySubtracting:
– decimalNumberByMultiplyingBy:
– decimalNumberByDividingBy:
– decimalNumberByRaisingToPower:
...
Якщо продуктивність обчислень представляє інтерес, перетворіть на масив C ++ std :: vector або подібний.
Зараз я більше ніколи не використовую C-масиви; занадто легко розбитися, використовуючи неправильний індекс або покажчик. І дуже нудно поєднувати кожен новий [] з delete [].
NSDecimalNumber
s, як перетворити NSDecimalNumber
результат назад на NSNumber
? (Це питання стосується додавання двох NSNumber
с, а не додавання двох NSDecimalNumber
с.)
@interface NSDecimalNumber : NSNumber
Можна використовувати
NSNumber *sum = @([first integerValue] + [second integerValue]);
Редагувати: Як спостерігав ohho , цей приклад стосується складання двох NSNumber
екземплярів, які містять цілі значення. Якщо ви хочете скласти два NSNumber
, що містять значення з плаваючою комою, вам слід зробити наступне:
NSNumber *sum = @([first floatValue] + [second floatValue]);
int
і long
чи це великий брат typedef
« під ред NSInteger
в NSNumber
об'єкти .
integerValue
усіки float
. Як за цю відповідь можна проголосувати?
integerValue
якщо хочете зберегти десяткову частину чисел?
Поточна відповідь з найбільшою оцінкою призведе до важко діагностуються помилок та втрати точності через використання плаваючих знаків. Якщо ви виконуєте числові операції зі значеннями NSNumber, вам слід спочатку перетворити на NSDecimalNumber і замість цього виконувати операції з цими об'єктами.
З документації :
NSDecimalNumber, незмінний підклас NSNumber, забезпечує об'єктно-орієнтовану обгортку для виконання арифметики base-10. Екземпляр може представляти будь-яке число, яке може бути виражене як показник mantissa x 10 ^, де mantissa - це десяткове ціле число довжиною до 38 цифр, а показник - ціле число від –128 до 127.
Отже, вам слід перетворити свої екземпляри NSNumber у NSDecimalNumbers за допомогою [NSNumber decimalValue]
, виконати будь-яку арифметику, яку ви хочете, а потім призначити назад NSNumber, коли закінчите.
У цілі-C:
NSDecimalNumber *a = [NSDecimalNumber decimalNumberWithDecimal:one.decimalValue]
NSDecimalNumber *b = [NSDecimalNumber decimalNumberWithDecimal:two.decimalValue]
NSNumber *result = [a decimalNumberByAdding:b]
У Swift 3:
let a = NSDecimalNumber(decimal: one.decimalValue)
let b = NSDecimalNumber(decimal: two.decimalValue)
let result: NSNumber = a.adding(b)
Чому б не використовувати 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"
Ви також можете створити вираз NSE, який можна використовувати повторно для оцінки за допомогою різних аргументів, наприклад:
NSExpression *expr = [NSExpression expressionWithFormat: @"(X+Y)"];
NSDictionary *parameters = [NSDictionary dictionaryWithObjectsAndKeys:x, @"X", y, @"Y", nil];
NSLog(@"%@", [expr expressionValueWithObject:parameters context:nil]);
Наприклад, ми можемо виконати цикл обчислення одного і того ж проаналізованого виразу кожного разу з різним значенням "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]);
}
У Swift ви можете отримати цю функцію за допомогою бібліотеки Bolt_Swift https://github.com/williamFalcon/Bolt_Swift .
Приклад:
var num1 = NSNumber(integer: 20)
var num2 = NSNumber(integer: 25)
print(num1+num2) //prints 45