Абсолютное значение (абс) NSDecimalNumber без потери точности - PullRequest
21 голосов
/ 11 мая 2009

Мне нужно получить абсолютное значение NSDecimalNumber без потери точности. Я не могу найти способ сделать это без преобразования в десятичную или с плавающей запятой (с потерей точности). Есть ли способ сделать это?

Ответы [ 4 ]

28 голосов
/ 11 мая 2009

Вы можете использовать встроенные функции класса NSDecimalNumber, чтобы сравнить число с нулем, а затем умножить на -1, если необходимо. Например:

<code>- (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, нет потери точности.

9 голосов
/ 28 октября 2010

В ответе есть небольшая ошибка: отрицательный должен быть указателем. Вот исправленный ответ:

- (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;
    }
}
4 голосов
/ 30 ноября 2017

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()
4 голосов
/ 08 июня 2015

Если вы не хотите умножать его, нулевое вычитание значения поможет.

- (NSDecimalNumber *)abs:(NSDecimalNumber *)num {
    if ([num compare:[NSDecimalNumber zero]] == NSOrderedAscending) {
        // negative value
        return [[NSDecimalNumber zero] decimalNumberBySubtracting:num];
    } else {
        return num;
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...