LondonGuy
LondonGuy

Reputation: 11098

Returned float value from NSString object is not what I expected, how do I correct extract a float from an NSString?

Working on the part of a shopping cart that adds up the total price of items.

I have this string £4.44 that is stored in core data.

I use this code to extra the numbers from the string:

+ (float)totalPriceOfItems:(NSManagedObjectContext *)managedObjectContext
{
    NSError *error = nil;
    float totalPrice = 0;

    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:@"BagItem"];

    // Get fetched objects and store in NSArray
    NSArray *fetchedObjects = [managedObjectContext executeFetchRequest:fetchRequest error:&error];

    for (BagItem *bagItem in fetchedObjects) {
        NSString *price = [[[bagItem price] componentsSeparatedByCharactersInSet:
                            [[NSCharacterSet decimalDigitCharacterSet] invertedSet]]
                           componentsJoinedByString:@""];
        totalPrice = totalPrice + [price floatValue];

        NSLog(@"total: %f", totalPrice);
    }

    return totalPrice;
}

I'm getting back this value 444.000000

When my intentions were to get back 4.44

I'm obvious missing something here and maybe storing the price of each item as an integer would be better but for now I'd like to make things work this way.

Thanks for your time

Upvotes: 0

Views: 264

Answers (1)

Brandon
Brandon

Reputation: 2417

The problem likely lies in your parsing code, where you call

[[[bagItem price] componentsSeparatedByCharactersInSet:
                        [[NSCharacterSet decimalDigitCharacterSet] invertedSet]]
                       componentsJoinedByString:@""]

What your doing is seperating the string on every character that isn't a digit, and then putting it back together. So the string 4.44 is being split at the decimal place and being put back together as 444. My suggestion is to store the price in such a way as to not require some parsing code where you need to use the value - you should be storing it as 4.44.

Now to the next problem - floats. Floats and Doubles don't have the precision you need in terms of a financial application. At some point your going to add 10.99 and 0.01 together and discover that the answer is not 11.0 but 11.000000000001 or something like that. For these types of situations you should be storing your number as an NSDecimalNumber and using the functions that class provides to do your calculations.

You can turn your string into an NSDecimalNumber as follows:

[NSDecimalNumber decimalNumberWithString:@"44.50"];

By using an NSDecimal number this also sets you up to us NSNumberFormatter to format your number as currency if you want to display it

[NSNumberFormatter localizedStringFromNumber:number numberStyle:NSNumberFormatterCurrencyStyle];

Upvotes: 1

Related Questions