5

NSNumber检查 a是否为分数的最佳方法是什么?

NumberIsFraction(@(0)); // NO;
NumberIsFraction(@(0.5)); // YES;
NumberIsFraction(@(1.0)); // NO;

在边境案件处理和绩效方面“最佳”。

4

4 回答 4

14

避免转换为具有较小域的类型:

BOOL NumberIsFraction(NSNumber *number) {
    double dValue = [number doubleValue];
    if (dValue < 0.0)
        return (dValue != ceil(dValue));
    else
        return (dValue != floor(dValue));
}
于 2012-09-03T15:12:39.007 回答
7

来自 Jonathan、hpique 和 prashant 的解决方案都有相同的错误:它们涉及强制转换NSNumber为固定精度类型(各种doublelong long等),如果值非常大,则会中断NSDecimalNumber。例如,接受的答案在NSDecimalNumber(string: "1000000000000000.1").

更正确的实现(作为扩展,在 Swift 中):

extension NSNumber {
    var isFraction: Bool {
        var decimal = decimalValue, decimalRounded = decimal
        NSDecimalRound(&decimalRounded, &decimal, 0, .down)
        return NSDecimalNumber(decimal: decimalRounded) != self
    }
}

或者在 Objective-C 中,作为一个全局函数:

BOOL NumberIsFraction(NSNumber *number) {
    NSDecimal rounded = number.decimalValue;
    NSDecimalRound(&rounded, &rounded, 0, NSRoundDown);
    return ![number isEqualToNumber:
        [[NSDecimalNumber alloc] initWithDecimal:rounded]];
}
于 2015-09-09T05:46:28.590 回答
4

我目前正在使用:

BOOL NumberIsFraction(NSNumber* number) {
    return ![number isEqualToNumber:@(number.longLongValue)];
}
于 2012-09-03T11:57:57.247 回答
1
-(BOOL) NumberIsFraction: (NSNumber*)number
{
   NSLog(@"%0.16g",number.doubleValue);
   NSLog(@"%d", number.intValue);
   double diff = number.doubleValue - number.intValue;
   if (diff>0)
     return YES;
   else return NO;
}
于 2012-09-04T11:34:45.490 回答