NSDecimalNumber的绝对值(绝对值),不会损失精度

时间:2009-05-10 22:39:51

标签: objective-c

我需要获得NSDecimalNumber的绝对值而不会损失精度。我似乎无法找到一种方法来做到这一点,而无需转换为十进制或浮点数(精度损失)。有没有办法做到这一点?

5 个答案:

答案 0 :(得分:28)

您可以使用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,因此不会损失精度。

答案 1 :(得分:9)

答案中有一个小错误: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;
    }
}

答案 2 :(得分:4)

如果你不想乘以它,零减去这个值就可以了。

- (NSDecimalNumber *)abs:(NSDecimalNumber *)num {
    if ([num compare:[NSDecimalNumber zero]] == NSOrderedAscending) {
        // negative value
        return [[NSDecimalNumber zero] decimalNumberBySubtracting:num];
    } else {
        return num;
    }
}

答案 3 :(得分: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()

答案 4 :(得分:0)

斯威夫特 5

您可以使用 magnitudeDecimal 属性:

extension NSDecimalNumber {
    var absValue: Self {
        .init(decimal: decimalValue.magnitude)
    }
}
let number = NSDecimalNumber(string: "-123.456")
let absNumber = number.absValue // 123.456