Update: This is a relatively old answer, but it looks like people are still finding it. I want to update this for the sake of correctness - I initially answered the question, because I just demonstrated how you can get certain decimal places from double , but I do not protect this as a way of representing currency information.
Never use floating point numbers to represent currency information. As soon as you start dealing with decimal numbers (as with dollars with cents), you enter possible floating point errors into your code. The computer cannot accurately represent all decimal values โโ( 1/100.0 , for example, 1 cent, is represented as 0.01000000000000000020816681711721685132943093776702880859375 on my machine). Depending on what currencies you plan to represent, it is always more correct to store the quantity in terms of its base quantity (in this case, a cent).
If you keep your dollar values โโin terms of whole cents, you will never encounter floating point errors for most operations, and it is trivially easy to convert cents to dollars for formatting. If you need to apply a tax, for example, or multiply the value of cents by double , do this to get a double value, apply the banker's rounding to round to the nearest cent and convert back to an integer.
This gets complicated if you are trying to support several different currencies, but there are ways to handle this.
tl; dr Do not use floating point numbers to represent the currency, and you will be much happier and more correct. NSDecimalNumber can accurately (and accurately) represent decimal values, but as soon as you convert to double / float , you run the risk of introducing floating point errors.
This can be done relatively easily:
- Get the
double value of a decimal number (this will work if the number is not too large to store in double size). - In a separate variable, cast
double to an integer. - Multiply both numbers by 100 to take into account the loss of accuracy (in fact, convert to cents) and subtract dollars from the original to get the number of cents.
- Return to string.
(This is a general formula for working with all decimal numbers - only a little glue code is needed to work with NSDecimalNumber to make it work).
In practice, it will look like this (in the NSDecimalNumber category):
- (NSString *)cents { double value = [self doubleValue]; unsigned dollars = (unsigned)value; unsigned cents = (value * 100) - (dollars * 100); return [NSString stringWithFormat:@"%02u", cents]; }