Search code examples
objective-cnsnumber

How to get the correct value and type of NSNumber?


I am creating an NSNumber from string by check if the string is float or int using NSNumberFormatter. I want to have a method to return what type the NSNumber holds and the correct value. It works for int, but not working for decimal numbers.

NSNumber *n;
enum CFNumberType _numberType;

- (instancetype)initWithString:(NSString *)string {
    self = [super init];
    if (self) {
        NSNumberFormatter *formatter = [NSNumberFormatter new];
        decimalPattern = @"\\d+(\\.\\d+)";
        if ([Utils matchString:string withPattern:decimalPattern]) {
            // Float
            formatter.numberStyle = NSNumberFormatterDecimalStyle;
            _numberType = kCFNumberDoubleType;
            n = [formatter numberFromString:string];
        } else {
            // Integer
            formatter.numberStyle = NSNumberFormatterNoStyle;
            _numberType = kCFNumberIntType;
            n = [formatter numberFromString:string];
        }
        self = [self initWithNumber:n];
    }
    return self;
}


- (CFNumberType)value {
    CFNumberType num;  // How to determine the type of num? 
    CFNumberGetValue((CFNumberRef)n, _numberType, &num);
    return num;
}

- (CFNumberType)numberType {
    return _numberType;
}

In the value method, if I specify float num, then it works for floating point. But I cannot use float because I want to make it work for int as well. How to do this?


Solution

  • I have found a solution for this. First check if the number is double and call the appropriate value method.

    - (BOOL)isDouble {
        if (_numberType == kCFNumberFloatType || _numberType == kCFNumberFloat32Type || _numberType == kCFNumberFloat64Type || _numberType == kCFNumberDoubleType) {
            return YES;
        }
        return NO;
    }
    
    - (double)doubleValue {
        if ([self isDouble]) {
            return [n doubleValue];
        }
        return 0.0;
    }
    
    - (int)intValue {
        if (![self isDouble]) {
            return [n intValue];
        }
        return 0;
    }