我需要获得NSDecimalNumber的绝对值而不会损失精度。我似乎无法找到一种方法来做到这一点,而无需转换为十进制或浮点数(精度损失)。有没有办法做到这一点?
答案 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)
您可以使用 magnitude
的 Decimal
属性:
extension NSDecimalNumber {
var absValue: Self {
.init(decimal: decimalValue.magnitude)
}
}
let number = NSDecimalNumber(string: "-123.456")
let absNumber = number.absValue // 123.456