Мне нужно получить абсолютное значение NSDecimalNumber без потери точности. Кажется, я не могу найти способ сделать это, не превращаясь в десятичный или плавающий (с потерей точности). Есть ли способ сделать это?
Абсолютная величина (абс.) NSDecimalNumber без потери точности
Ответ 1
Вы можете использовать встроенные функции класса NSDecimalNumber для сравнения числа с нолем, а затем умножить на -1, если это необходимо. Например:
- (NSDecimalNumber *)abs:(NSDecimalNumber *)num {
if ([num compare:[NSDecimalNumber zero]] == NSOrderedAscending) {
// Number is negative. Multiply by -1
NSDecimalNumber * negativeOne = [NSDecimalNumber decimalNumberWithMantissa:1
exponent:0
isNegative:YES];
return [num decimalNumberByMultiplyingBy:negativeOne];
} else {
return num;
}
}
Поскольку этот метод работает исключительно с NSDecimalNumbers, нет потери точности.
Ответ 2
В ответе есть небольшая ошибка: negativeOne должен быть указателем. Вот отредактированный ответ:
- (NSDecimalNumber *)abs:(NSDecimalNumber *)num {
if [myNumber compare:[NSDecimalNumber zero]] == NSOrderedAscending) {
// Number is negative. Multiply by -1
NSDecimalNumber *negativeOne = [NSDecimalNumber decimalNumberWithMantissa:1
exponent:0
isNegative:YES];
return [num decimalNumberByMultiplyingBy:negativeOne];
} else {
return num;
}
}
И вот версия, подходящая для использования в качестве категории в NSDecimalNumber:
- (NSDecimalNumber *)abs {
if ([self compare:[NSDecimalNumber zero]] == NSOrderedAscending) {
// Number is negative. Multiply by -1
NSDecimalNumber *negativeOne = [NSDecimalNumber decimalNumberWithMantissa:1
exponent:0
isNegative:YES];
return [self decimalNumberByMultiplyingBy:negativeOne];
} else {
return self;
}
}
Ответ 3
Если вы не хотите его умножать, нулевое вычитание значения сделает трюк.
- (NSDecimalNumber *)abs:(NSDecimalNumber *)num {
if ([num compare:[NSDecimalNumber zero]] == NSOrderedAscending) {
// negative value
return [[NSDecimalNumber zero] decimalNumberBySubtracting:num];
} else {
return num;
}
}
Ответ 4
Вариант Swift 4.0:
extension NSDecimalNumber {
func absoluteValue() -> NSDecimalNumber {
if self.compare(NSDecimalNumber.zero) == .orderedAscending {
let negativeValue = NSDecimalNumber(mantissa: 1, exponent: 0, isNegative: true)
return self.multiplying(by: negativeValue)
} else {
return self
}
}
}
Использование
let sum = NSDecimalNumber(value: -123.33)
sum.absoluteValue()