views:

305

answers:

4

I have a price that I need to convert based on the selected currency.

NSString *path = [[NSBundle mainBundle] bundlePath];
NSString *finalPath = [path stringByAppendingPathComponent:@"currency.plist"];
NSDictionary *plistDictionary = [[NSDictionary dictionaryWithContentsOfFile:finalPath] retain];

int price = [price intValue];
int currencyValue = [[plistDictionary valueForKey:@"EUR"] intValue];
int convertedCurrency = (price / currencyValue);

price is an NSNumber and the valueForKey is also a number from a plist file I have setup with conversion rates.

The problem I am having, is that my price is missing the decimals. Everytime I get the intValue from the price it's just rounded up or down. The same issue exists for the exchange rate I get from the plist.

I have looked into NSNumberFormatter but it won't let me setFormat for the NSNumberFormatter. Any advice, please?

+1  A: 

intValue returns an integer, which (by definition) is rounded to a number without decimals.

You could use doubleValue, which returns a double (which does have the fractional portion) or decimalValue which returns a NSDecimal object.

Philippe Leybaert
+3  A: 

int is an integer type - by definition it does not have a decimal value. Instead try:

float fprice = [price floatValue];
float currencyValue = [[plistDictionary valueForKey:@"EUR"] floatValue];
float convertedCurrency = (fprice / currencyValue);
fbrereto
Thanks.. That sort of worked. Although now I am getting a lot of numbers.For example, the fprice I have is 42.35 and now it writes 42.3499985 and for the currencyValue is 7.44999981 instead if 7.45
Canada Dev
Those are rounding errors that can be fixed by adjusting the format of your print routine. What's your code to output the value(s)?
fbrereto
Right now all I just NSLog them... This is the log:fprice 42.349998currencyValue 7.450000convertedCurrency 5.684564Using: NSLog([NSString stringWithFormat:@"fprice %f", fprice]);
Canada Dev
Try using `%.2f` instead of `%f` -- that'll limit the output to two decimal points.
fbrereto
When dealing with currency, you may wish to use NSDecimalNumbers in order to avoid these kinds of floating point errors: http://stackoverflow.com/questions/421463/should-i-use-nsdecimalnumber-to-deal-with-money
Brad Larson
+1 on the `NSDecimalNumber` recommendation
fbrereto
A: 

To deal with the exact number of deciamlas and if all your currencies have 2 decimal places (e.g not JPY) make all numbers the number of cents e.g. store 43.35 EUR as 4235.

Then you can use in arithmetic and then just deal with formatting using value/100.0 and NSNumberFormatter

Mark
A: 

Take the price string and remove the period. After that convert the NSString to and int, which means you end up with 4235 pennies (or 42 dollars and 35 cents). (Also, make sure that the price string you're getting has two decimal places! Some people are lazy, and output "3.3" for "$3.30".)

NSString *removePeriod = [price stringByReplacingOccurrencesOfString:@"." withString:@""];
int convertedPrice = [removePeriod intValue];
float exchangeRate;

Then get the exchange rates depending on which currency has been selected and use the following code:

int convertedCurrency = round((double)convertedPrice / exchangeRate);
addCurrency = [NSString stringWithFormat: @"%0d.%02d", (convertedCurrency / 100), (convertedCurrency % 100)];

addCurrency is your final price.

bwinton
Worked perfectly!!! Thanks
Canada Dev