2012-09-03 19 views
5

¿Cuál es la mejor manera de verificar si un NSNumber es una fracción?Compruebe si NSNumber es la fracción

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

"Mejor" en términos de manejo de casos fronterizos y rendimiento.

Respuesta

13

Evitar las conversiones de tipos con un dominio más pequeño:

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

Creo que esos deberían ser '! ='? 'NumberIsFraction (@ (0.0f))' devolvería 'SÍ', ¿no? – hypercrypt

+0

Ah, sí, brainfart. :) –

3

actualmente estoy usando:

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

que funcione para muchos enteros, pero muy grande o los enteros muy negativos se romperán durante la conversión a/desde '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

Las soluciones de Jonathan, hpique y Prashant todos tienen el mismo error : implican la conversión de NSNumber a tipos de precisión fija (diversamente double, long long, etc.), que se rompe si el valor es muy grande NSDecimalNumber. Por ejemplo, la respuesta aceptada falla en NSDecimalNumber(string: "1000000000000000.1").

Una aplicación más seguro (como una extensión, en 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 } 
} 

O en Objective-C, como una función global:

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