Тепер це має бути легко, але як можна підсумувати два 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 [].
NSDecimalNumbers, як перетворити 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