Objective c 如何得到整数和小数除法的模(mod)

Objective c 如何得到整数和小数除法的模(mod),objective-c,cocoa,cocoa-touch,nsnumber,Objective C,Cocoa,Cocoa Touch,Nsnumber,我对小数及其“行为”感到困惑。我有一个代表美元价值的小数,比如37.50美元。我想知道有多少次说5.0进入了这个数字,然后知道剩下的是什么。我可以直接除法得到7.50,但我想要7模2.50。我可以转换为整数,但需要保存“美分”,因此想知道框架中是否有一些技巧?理论上,您可以使用NSDecimalNumber方法DecimalNumberByDivingBy:,decimalNumberByMultiplyingBy:,和decimalValue。除以数字,获取十进制数字结构,从结构中计算出余数,

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

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

然而,更简单的方法可能是计算出所需的最大精度(在小数点后称为N位),将数字乘以10eN,然后只需获取整数值并对其进行除法和模运算。但是,您有丢失数据的风险,特别是对于非常大的数据,因此请检查您想要的最大数据,并找出适合您的数据类型(如果有)。NSNumber不支持
unsignedLongValue

  • 将股息除以除数,四舍五入。这就是商
  • 将除数乘以商
  • 从股息中减去。这就得到了剩余部分
  • (37.50//5)=7;7 * 5 == 35; 37.50-35=2.50


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

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

    这里有一个
    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;
    }
    

    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
     { ...
    

    要进行四舍五入,请使用math.h中的floor()-它接受一个double并返回一个double。如果使用的是十进制数,请尽量保持在该类型内。也就是说,要使用DecimalNumberByRoundingAccordingBehavior:。四舍五入,最好使用
    DecimalNumberByDivingBy:withBehavior:
    进行除法。那么你就不需要单独四舍五入了。注意,这在负红利或负除数的情况下是不正确的。我在下面发布了一个处理这些情况的
    NSDecimalNumber
    类别。如果除数或除数之一为负数,则必须设置右舍入模式<代码>NSRoundingMode roundingMode=((divident.floatValue<0)^(divisior.floatValue<0))?nsrundup:nsrunddown