Always always always the proper way to convert a string into a number is to use an NSNumberFormatter
. Using methods like -floatValue
and -intValue
can lead to false positives.
Behold:
NSNumberFormatter * nf = [[NSNumberFormatter alloc] init];
[nf setNumberStyle:NSNumberFormatterDecimalStyle];
NSString * good = @"42.69";
NSString * bad = @"42.69abc";
NSString * abc = @"abc";
NSString * zero = @"0";
NSLog(@"-[good floatValue]: %f", [good floatValue]);
NSLog(@"-[bad floatValue]: %f", [bad floatValue]);
NSLog(@"-[abc floatValue]: %f", [abc floatValue]);
NSLog(@"-[zero floatValue]: %f", [zero floatValue]);
NSNumber * goodNumber = [nf numberFromString:good];
NSNumber * badNumber = [nf numberFromString:bad];
NSNumber * abcNumber = [nf numberFromString:abc];
NSNumber * zeroNumber = [nf numberFromString:zero];
NSLog(@"good (NSNumber): %@", goodNumber);
NSLog(@"bad (NSNumber): %@", badNumber);
NSLog(@"abc (NSNumber): %@", abcNumber);
NSLog(@"zero (NSNumber): %@", zeroNumber);
[nf release];
This logs:
2011-01-07 09:50:07.881 EmptyFoundation[4895:a0f] -[good floatValue]: 42.689999
2011-01-07 09:50:07.884 EmptyFoundation[4895:a0f] -[bad floatValue]: 42.689999
2011-01-07 09:50:07.885 EmptyFoundation[4895:a0f] -[abc floatValue]: 0.000000
2011-01-07 09:50:07.885 EmptyFoundation[4895:a0f] -[zero floatValue]: 0.000000
2011-01-07 09:50:07.886 EmptyFoundation[4895:a0f] good (NSNumber): 42.69
2011-01-07 09:50:07.887 EmptyFoundation[4895:a0f] bad (NSNumber): (null)
2011-01-07 09:50:07.887 EmptyFoundation[4895:a0f] abc (NSNumber): (null)
2011-01-07 09:50:07.888 EmptyFoundation[4895:a0f] zero (NSNumber): 0
Observations:
- The
-floatValue
of a non-numeric string (@"42.69abc"
and @"abc"
) results in a false positive (of 0.000000
)
- If a string is not numeric,
NSNumberFormatter
will report it as nil
As an added bonus, NSNumberFormatter
takes locale into account, so it'll (correctly) recognize "42,69" as numeric, if the current locale has ,
set as the decimal separator.
TL;DR:
Use NSNumberFormatter
.