Objective c 如何得到整数和小数除法的模(mod)
我对小数及其“行为”感到困惑。我有一个代表美元价值的小数,比如37.50美元。我想知道有多少次说5.0进入了这个数字,然后知道剩下的是什么。我可以直接除法得到7.50,但我想要7模2.50。我可以转换为整数,但需要保存“美分”,因此想知道框架中是否有一些技巧?理论上,您可以使用NSDecimalNumber方法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。除以数字,获取十进制数字结构,从结构中计算出余数,
DecimalNumberByDivingBy:
,decimalNumberByMultiplyingBy:
,和decimalValue
。除以数字,获取十进制数字结构,从结构中计算出余数,然后用余数创建一个新的十进制数字,并将余数乘以原始数字
然而,更简单的方法可能是计算出所需的最大精度(在小数点后称为N位),将数字乘以10eN,然后只需获取整数值并对其进行除法和模运算。但是,您有丢失数据的风险,特别是对于非常大的数据,因此请检查您想要的最大数据,并找出适合您的数据类型(如果有)。NSNumber不支持unsignedLongValue
(注意:
/
是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代码>