Теперь это должно быть легко, но как сложить два NSNumber
? Как:
[one floatValue] + [two floatValue]
или существует лучший способ?
Теперь это должно быть легко, но как сложить два 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:
...
Если вас интересует производительность вычислений, конвертируйте в массив С++ std::vector или тому подобное.
Теперь я больше никогда не использую C-Arrays; слишком легко сбой, используя неправильный индекс или указатель. И очень утомительно соединять каждый новый [] с delete[].
NSDecimalNumber
как преобразовать результат NSDecimalNumber
обратно в NSNumber
? (Этот вопрос касается добавления двух NSNumber
, а не добавления двух NSDecimalNumber
.)
- person ohho; 05.02.2013
@interface NSDecimalNumber : NSNumber
- person Steven Fisher; 06.12.2013
Ты можешь использовать
NSNumber *sum = @([first integerValue] + [second integerValue]);
Изменить: как заметил ohho, этот пример предназначен для сложения двух экземпляров NSNumber
, которые содержат целочисленные значения. Если вы хотите сложить два NSNumber
, которые содержат значения с плавающей запятой, вы должны сделать следующее:
NSNumber *sum = @([first floatValue] + [second floatValue]);
int
или long
, или его старший брат typedef
'ed NSInteger
в NSNumber
объекты.
- person nemesis; 07.01.2014
integerValue
усекает float
. Как за этот ответ можно проголосовать?
- person ohho; 08.04.2014
integerValue
, если вы хотите сохранить десятичную часть чисел?
- person nemesis; 08.04.2014
Текущий ответ с наибольшим количеством голосов приведет к труднодиагностируемым ошибкам и потере точности из-за использования поплавки. Если вы выполняете числовые операции со значениями NSNumber, вы должны сначала преобразовать в NSDecimalNumber и вместо этого выполнять операции с этими объектами.
Из документации:
NSDecimalNumber, неизменяемый подкласс NSNumber, предоставляет объектно-ориентированную оболочку для выполнения десятичной арифметики. Экземпляр может представлять любое число, которое может быть выражено как мантисса x 10 ^ показатель степени, где мантисса — это десятичное целое число длиной до 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]
В Свифт 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"
Вы также можете создать NSExpression, который можно повторно использовать для оценки с различными аргументами, например:
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