Check if NSNumber is fraction
Asked Answered
C

4

5

What is the best way of checking if a NSNumber is a fraction?

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

"Best" in terms of border case handling and performance.

Crimmer answered 3/9, 2012 at 11:57 Comment(0)
A
13

Avoiding conversions to types with a smaller domain:

BOOL NumberIsFraction(NSNumber *number) {
    double dValue = [number doubleValue];
    if (dValue < 0.0)
        return (dValue != ceil(dValue));
    else
        return (dValue != floor(dValue));
}
Amhara answered 3/9, 2012 at 15:12 Comment(1)
I think those should be !=? NumberIsFraction(@(0.0f)) would return YES, wouldn't it?Tripping
I
8

The solutions from Jonathan, hpique, and prashant all have the same bug: they involve casting NSNumber to fixed-precision types (variously double, long long, etc.), which breaks if the value is a very large NSDecimalNumber. For example, the accepted answer fails on NSDecimalNumber(string: "1000000000000000.1").

A more correct implementation (as an extension, in Swift):

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

Or in Objective-C, as a global function:

BOOL NumberIsFraction(NSNumber *number) {
    NSDecimal rounded = number.decimalValue;
    NSDecimalRound(&rounded, &rounded, 0, NSRoundDown);
    return ![number isEqualToNumber:
        [[NSDecimalNumber alloc] initWithDecimal:rounded]];
}
Incubator answered 9/9, 2015 at 5:46 Comment(0)
C
4

I'm currently using:

BOOL NumberIsFraction(NSNumber* number) {
    return ![number isEqualToNumber:@(number.longLongValue)];
}
Crimmer answered 3/9, 2012 at 11:57 Comment(1)
That will work for many integers, but very large or very negative integers will break during conversion to/from long long.Amhara
R
0
-(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;
}
Ratchet answered 4/9, 2012 at 11:34 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.