2012-09-03 29 views
5

檢查NSNumber是否是分數的最佳方法是什麼?檢查NSNumber是否是分數

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

出界的情況下,處理和性能方面的「最佳」。

回答

13

避免轉換到類型以較小的領域:

BOOL NumberIsFraction(NSNumber *number) { 
    double dValue = [number doubleValue]; 
    if (dValue < 0.0) 
     return (dValue != ceil(dValue)); 
    else 
     return (dValue != floor(dValue)); 
} 
+0

我認爲這些應該是'!='? NumberIsFraction(@(0.0f))'會返回YES,不是嗎? – hypercrypt

+0

啊,是的,brainfart。 :) –

3

我目前使用:

BOOL NumberIsFraction(NSNumber* number) { 
    return ![number isEqualToNumber:@(number.longLongValue)]; 
} 
+1

將爲許多整數的工作,但是非常大或者非常負的整數在轉換爲/ long long期間會中斷。 –

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; 
} 
4

喬納森,hpique的解決方案,並PRASHANT都具有相同的錯誤:他們涉及將NSNumber轉換爲固定精度類型(各種double,long long等),如果該值非常大,則會中斷NSDecimalNumber。例如,接受的答案在NSDecimalNumber(string: "1000000000000000.1")上失敗。

一個更安全的實現(作爲擴展,在SWIFT):

extension NSNumber { 
    var isInteger: Bool { 
     var rounded = decimalValue 
     NSDecimalRound(&rounded, &rounded, 0, NSRoundingMode.RoundDown) 
     return NSDecimalNumber(decimal: rounded) == self 
    } 

    var isFraction: Bool { return !isInteger } 
} 

或者在Objective-C,作爲一個全球性的功能:

BOOL NumberIsFraction(NSNumber *number) { 
    NSDecimal rounded = number.decimalValue; 
    NSDecimalRound(&rounded, &rounded, 0, NSRoundDown); 
    return ![number isEqualToNumber: 
     [[NSDecimalNumber alloc] initWithDecimal:rounded]]; 
}