如何使用NSDecimalNumber获得除法的int和modulo(mod)

时间:2009-07-24 03:20:28

标签: objective-c cocoa cocoa-touch nsnumber

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

5 个答案:

答案 0 :(得分:7)

使用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];

答案 1 :(得分: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;
}

答案 2 :(得分:5)

  1. 将除数除以除数,向下舍入。这可以获得商数。
  2. 用商除数除数。
  3. 从股息中减去。这可以让你得到余下的。
  4. (37.50 // 5)== 7; 7 * 5 == 35; 37.50 - 35 = 2.50。

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

答案 3 :(得分:1)

理论上你可以使用NSDecimalNumber方法decimalNumberByDividingBy:decimalNumberByMultiplyingBy:decimalValue做一些技巧。划分数字,获取十进制数字结构,找出结构中的余数,然后用该余数创建一个新的十进制数,并将该余数乘以原始数。

然而,更简单的方法可能是找出你想要的最大精度(在小数点后称之为N位),将数字乘以10eN,然后只需获取整数值并进行划分和mod。然而,您冒着丢失数据的风险,特别是对于非常大的数据,请检查您想要的最大数字,并确定哪种数据类型 - 如果有的话 - 将适合您。 NSNumber确实支持unsignedLongLongValue

答案 4 :(得分:0)

Swift 4中的相同解决方案:

Do While I <= UBound(xFilesToOpen)