8

我对 NSDecimalNumber 及其“行为”感到困惑。我有一个代表美元价值的 NSDecimalNumber,比如 37.50 美元。我想知道有多少次说 5.0 进入那个数字,然后知道剩下的是什么。我可以得到直接除法并得到 7.50,但我想要 7 mod 2.50。我可以转换为整数,但需要保存“美分”,所以想知道框架中是否有一些技巧?

4

5 回答 5

9

使用 Peter Hoseys 示例,但使用 iOS 代码:

NSDecimalNumber *dividend = [NSDecimalNumber decimalNumberWithDecimal:[[NSNumber numberWithDouble:37.5] decimalValue]];

NSDecimalNumber *divisor = [NSDecimalNumber decimalNumberWithDecimal:[[NSNumber numberWithDouble:5.0] decimalValue]];

NSDecimalNumber *quotient = [dividend decimalNumberByDividingBy:divisor withBehavior:[NSDecimalNumberHandler decimalNumberHandlerWithRoundingMode:NSRoundDown scale:0 raiseOnExactness:NO raiseOnOverflow:NO raiseOnUnderflow:NO raiseOnDivideByZero:NO]];

NSDecimalNumber *subtractAmount = [quotient decimalNumberByMultiplyingBy:divisor];

NSDecimalNumber *remainder = [dividend decimalNumberBySubtracting:subtractAmount];
于 2011-07-29T15:27:04.410 回答
6

这是一个NSDecimalNumber也适用于负数和负除数的类别:

- (BOOL)isNegative
{
    return (NSOrderedDescending == [[NSDecimalNumber zero] compare:self]);
}

- (NSDecimalNumber *)invertedNumber
{
    NSDecimalNumber *negOne = [NSDecimalNumber decimalNumberWithMantissa:1 exponent:0 isNegative:YES];
    return [self decimalNumberByMultiplyingBy:negOne];
}

- (NSDecimalNumber *)moduloFor:(NSDecimalNumber *)divisor
{
    NSRoundingMode roundingMode = ([self isNegative] ^ [divisor isNegative]) ? NSRoundUp : NSRoundDown;
    NSDecimalNumberHandler *rounding = [NSDecimalNumberHandler decimalNumberHandlerWithRoundingMode:roundingMode
                                                                                              scale:0
                                                                                   raiseOnExactness:NO
                                                                                    raiseOnOverflow:NO
                                                                                   raiseOnUnderflow:NO
                                                                                raiseOnDivideByZero:NO];

    // divide and get the remainder
    NSDecimalNumber *quotient = [self decimalNumberByDividingBy:divisor withBehavior:rounding];
    NSDecimalNumber *subtract = [quotient decimalNumberByMultiplyingBy:divisor];

    NSDecimalNumber *modulo = [self decimalNumberBySubtracting:subtract];
    if ([divisor isNegative]) {
        return [modulo invertedNumber];
    }
    return modulo;
}
于 2013-02-21T17:50:10.603 回答
6
  1. 将除数除以除数,四舍五入。这会让你得到商数。
  2. 将除数乘以商。
  3. 从股息中减去。这会给你剩下的。

(37.50 // 5) == 7; 7 * 5 == 35;37.50 - 35 = 2.50。

(注意://是 Python 的整数除法运算符。我在这里借用了它。显然,您实际上不应该尝试//在 Objective-C 代码中使用除法。)

于 2009-07-24T03:34:17.700 回答
3

Swift 4 中的相同解决方案:

    let dividend = NSDecimalNumber(string: Price)
    let divisor = NSDecimalNumber(decimal: 0.05)
    let quotient = dividend.dividing(by: divisor, withBehavior: NSDecimalNumberHandler(roundingMode: .down, scale: 0, raiseOnExactness: false, raiseOnOverflow: false, raiseOnUnderflow: false, raiseOnDivideByZero: false))
    let subtractAmount = quotient?.multiplying(by: divisor)
    let remainder = dividend.subtracting(anAmount)
 if remainder != 0
 { ...
于 2018-04-11T07:35:01.570 回答
1

理论上,您可以使用 NSDecimalNumber 方法decimalNumberByDividingBy:decimalNumberByMultiplyingBy:decimalValue. 除以数字,获取十进制数字结构,从结构中找出余数,然后用该余数创建一个新的十进制数,并将该余数乘以原始数字。

然而,更简单的方法可能是计算出您想要的最大精度(称为小数点后 N 位),将数字乘以 10eN,然后获取整数值并进行除法和 mod on那。但是,您冒着丢失数据的风险,尤其是对于非常大的数字,因此请检查您想要的最大数字并找出适合您的数据类型(如果有的话)。NSNumber 确实支持unsignedLongLongValue.

于 2009-07-24T03:32:41.727 回答