views:

583

answers:

2

Hello everyone, I have trouble when I have currency value

999999999999999999.99

From that value, I want to display it as String. The problem is that value always rounded to

1000000000000000000.00

I'm not expect that value rounded. I want the original value displayed. Do you have any idea how to solve this problem? I tried this code from some answer/turorial in stackoverflow.com :

NSMutableString *aString = [NSMutableString stringWithCapacity:30];

NSNumberFormatter *aCurrency = [[NSNumberFormatter alloc]init];
[aCurrency setFormatterBehavior:NSNumberFormatterBehavior10_4];
[aCurrency setNumberStyle:NSNumberFormatterCurrencyStyle];   
[aCurrency setMinimumFractionDigits:2];
[aCurrency setMaximumFractionDigits:2];
[aString appendString:[aCurrency stringFromNumber:productPrice]];
//productPrice is NSDecimalNumber which is have value 999999999999999999.99

cell.textLabel.text = aString;
NSLog(@"the price = %@",cell.textLabel.text);
//it prints $1,000,000,000,000,000,000.00
[aCurrency release];
A: 

Have you tried these:

* – setRoundingBehavior:
* – roundingBehavior
* – setRoundingIncrement:
* – roundingIncrement
* – setRoundingMode:
* – roundingMode
Sjoerd
+4  A: 

Unless you have very good reasons not to, it is generally best to keep currency values in a fixed-point format, rather than floating point. Ada supports this directly, but for C-ish languages what you do is keep the value in units of pennies, rather than dollars, and only do the conversion whenever you go to display it.

So in this case the value of productPrice would be 99999999999999999999 (cents). To display it, you'd do something like this (If this were C. I don't know the language):

int const modulus = productPrice % 100;
printf ("The price = %d.%d\n", (int) ((productPrice - modulus) / 100), modulus);

I'd also use an integer rather than a floating point variable to keep the value in almost all cases. It won't work in this case (even if you use a 64-bit integer) because your value is mind-bogglingly large. We're talking 1 million times larger than the US National Debt! If a dollar value that large ever makes sense for anything in my lifetime, we are all in big trouble.

T.E.D.
It's perfectly valid to use NSDecimal and NSDecimalNumber for storing currency values, because they do base-10 math, avoiding the decimal representation issues of normal floating point types. They also provide up to 38 digits of precision. See here: http://stackoverflow.com/questions/421463/should-i-use-nsdecimalnumber-to-deal-with-money
Brad Larson
After doing some research, it looks like you are right, with the proviso that it has this exact problem with rounding. What you really want for currency (most of the time) is fixed point types, as that's what (US) currency is.
T.E.D.