How to properly display currency iPhone/Objective-C - objective-c

I am trying to properly display properly formatted currencies from long values. I am using NSNumberFormatter however it seems to be cutting off my decimal places where the cents would go.
For example, if I have a long value of 1203 (cents) I want it to have a fixed point format (like 12.03). Here is what I have done:
NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
formatter.numberStyle = NSNumberFormatterCurrencyStyle;
formatter.currencyCode = "USD";
formatter.multiplier = [NSNumber numberWithDouble:0.01];
long currencyAmount = 1203;
NSNumber *number = [NSNumber numberWithLongLong:currencyAmount];
[label setText:[formatter stringFromNumber:number]];
I am getting this output $12.00 but I want $12.03

To think of an integer cut-off bug inside of NSNumberFormatter is crazy speculation but have you tried the default multiplier of one and dividing your currency amount after conversion to float by 100 yourself?
EDIT: For this workaround the following post suggests the use of NSDecimalNumber to avoid rounding problems. NSNumberFormatter to format currency not working for floats

I figured out the answer. This will properly format a long/long long value to a currency.
NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
formatter.numberStyle = NSNumberFormatterCurrencyStyle;
formatter.currencyCode = "USD";
long currencyAmount = 1203;
NSDecimalNumber *wrappedCurrencyAmount = [NSDecimalNumber decimalNumberWithMantissa:currencyAmount exponent:-2 isNegative:NO];
[label setText:[formatter stringFromNumber:wrappedCurrencyAmount]];

Related

What's the intended way to turn a NSString into a NSDecimalNumber with two decimal places?

I'm currently using the following methodology to turn a NSString number (like #"123.456") into a NSDecimalNumber after rounding (like 123.46), but it feels hacky. Is there a more intended solution?
+ (NSDecimalNumber*)decimalNumberForString:(NSString*)str accuracy:(NSUInteger)accuracy
{
NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
formatter.numberStyle = NSNumberFormatterNoStyle;
formatter.maximumFractionDigits = accuracy;
formatter.roundingMode = NSNumberFormatterRoundHalfUp;
NSNumber *numberVersion = [formatter numberFromString:str];
return [[NSDecimalNumber alloc] initWithDecimal:numberVersion.decimalValue];
}
Take a look at NSDecimalNumberHandler and NSDecimalNumber's
-decimalNumberByRoundingAccordingToBehavior:
method.
You can create a NSDecimalNumber with your unedited string, then create a new NSDecimal number that's rounded according to the rules you set on NSDecimalNumberHandler.
There's no need to edit your input string.
Use [NSDecimalNumber decimalNumberWithString:], like this:
NSDecimalNumber *number = [NSDecimalNumber decimalNumberWithString:#"123.456"];
The number of decimal places only affects the string representation of the number; once the number is stored in an NSDecimalNumber object it can be formatted back to a string in any way you desire.

How to display leading zero in double

I need to make NSNumber to display only 4 decimal points. This part of code is works, but it outputs result without leading zero.
double resultRoundToDecimal = [result doubleValue];
NSNumberFormatter *resultFormatter = [[NSNumberFormatter alloc] init];
[resultFormatter setRoundingMode:NSNumberFormatterRoundHalfUp];
[resultFormatter setMaximumFractionDigits:4];
resultData = [resultFormatter stringFromNumber:[NSNumber numberWithDouble:resultRoundToDecimal]];
For example:
1/3 = .3333
I want:
1/3 = 0.3333
How I can to do this?
You could choose to use string formatter too, like below
float val=1./3;
NSString *resultData=[NSString stringWithFormat:#"%0.4f",val];
NSLog(#"Result = %#",resultData);
Prepend a 0 or use number formatter.
NSString *printStr = #"0";
printStr = [NSString stringByAppendingString: resultData];
Otherwise, you could use a number formatter or something similar. If your just outputting a string why not do that?
https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSNumberFormatter_Class/Reference/Reference.html

convert NSString TO NSNumber accurately with decimal

Lets say my string value is as follows
12345.12
after converting it to NSNumber its coming as 12345.1223122
But I want the accurate number from string
Is there a way to achieve it.
Code that I'm using right now
NSNumberFormatter * f = [[NSNumberFormatter alloc] init];
[f setNumberStyle:NSNumberFormatterCurrencyStyle];
NSNumber * myNumber = [f numberFromString:aString];
[f release];
If you're dealing with currency-type numbers (just a guess from your use of the currency style formatter) you probably want to use NSDecimalNumber. Unlike standard floating point types, decimal numbers use a base-10 exponent so that you always get exactly the expected accuracy when dealing with money problems — i.e. they're the same as using integers and then moving the decimal point around in the base-10 representation.
Try Like this...
NSNumberFormatter * f = [[NSNumberFormatter alloc] init];
[f setNumberStyle:NSNumberFormatterCurrencyStyle];
NSNumber * myNumber=[NSNumber numberWithFloat:[[f numberFromString:aString] floatValue]];
I think it will be helpful to you.
Do this:
NSNumberFormatter * f = [[NSNumberFormatter alloc] init];
[f setNumberStyle:NSNumberFormatterDecimalStyle];
[f setMaximumFractionDigits:2];
NSNumber * myNumber = [f numberFromString:aString];
[f release];
NSLog(#"%#",myNumber);
It's a few years, but this works:
double d = [#"123.45" doubleValue];
NSNumber* n = [NSNumber numberWithDouble:d];

NSNumberFormatter, appending decimal to calculator from UI

Ok, so I am writing a calculator app now. So far, I'm not having much luck in regard to decimals (my most recent approach hasn't worked well).
-(void) DecimalAdded
{
NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
[formatter setNumberStyle:NSNumberFormatterDecimalStyle];
[formatter setAlwaysShowsDecimalSeparator:YES];
[formatter setGeneratesDecimalNumbers:YES];
[formatter setDecimalSeparator:#"."];
//first convert the float value of CN into NSnumber
NSNumber *nextstepNumFromCNF= [NSNumber numberWithFloat:currentNumber];
//now we have to convert that number into a string
NSString *CNconverted = [formatter stringFromNumber:nextstepNumFromCNF];
NSNumber *CNdecmAddedAndReadyForPars = [formatter numberFromString:CNconverted];
currentNumber = currentNumber*10 + [CNdecmAddedAndReadyForPars floatValue];
CalculatorScreen = [NSMutableString stringWithFormat: #"%#", CNconverted];
I can append the string to the Calculator screen I can say the number is 1, I see "1." as I'm typing. However this is usually converted to 1 during th float conversion (which is correct).
What is this best way to accomplish this?

How to add commas to number every 3 digits in Objective C?

If I have a number int aNum = 2000000 how do I format this so that I can display it as the NSString 2,000,000?
Use NSNumberFormatter.
Specifically:
NSNumberFormatter *formatter = [NSNumberFormatter new];
[formatter setNumberStyle:NSNumberFormatterDecimalStyle]; // this line is important!
NSString *formatted = [formatter stringFromNumber:[NSNumber numberWithInteger:2000000]];
[formatter release];
By default NSNumberFormatter uses the current locale so the grouping separators are set to their correct values by default. The key thing is to remember to set a number style.
Don't do your own number formatting. You will almost certainly not get all the edge cases right or correctly handle all possible locales. Use the NSNumberFormatter for formatting numeric data to a localized string representation.
You would use the NSNumberFormatter instance method -setGroupingSeparator: to set the grouping separator to #"," (or better yet [[NSLocale currentLocale] objectForKey:NSLocaleGroupingSeparator]; thanks #ntesler) and -setGroupingSize: to put a grouping separator every 3 digits.
There's a static method on NSNumberFormatter that does just what you need:
int aNum = 2000000;
NSString *display = [NSNumberFormatter localizedStringFromNumber:#(aNum)
numberStyle:NSNumberFormatterDecimalStyle];
This way is a little more succinct than creating a new NSNumberFormatter if you don't need to do any additional configuration of the formatter.
Even easier:
NSNumber *someNumber = #(1234567890);
NSString *modelNumberString = [NSString localizedStringWithFormat:#"%#", someNumber];
NSLog(#"Number with commas: %#", modelNumberString);
coworker just taught me this today. #amazing
Think some as i will get this post looking for sample.
So if you are working with number make attention on next params:
setNumberStyle:NSNumberFormatterCurrencyStyle // if you are working with currency
It could be also
setNumberStyle:NSNumberFormatterDecimalStyle
All code is For ARC.
If you are working with Integer and need to get result such as 200,000
int value = 200000;
NSNumberFormatter * formatter = [NSNumberFormatter new];
[formatter setNumberStyle:NSNumberFormatterDecimalStyle];
NSString * newString = [formatter stringFromNumber:[NSNumber numberWithInteger:value]];
If you are working with Float and need to get result such as 200,000.00
float value = 200000;
NSNumberFormatter * formatter = [NSNumberFormatter new];
[formatter setNumberStyle:NSNumberFormatterDecimalStyle];
[formatter setMaximumFractionDigits:2]; // Set this if you need 2 digits
NSString * newString = [formatter stringFromNumber:[NSNumber numberWithFloat:value]];
EDIT
To have ability to use different digital separators use NSLocale.
Add to code where NSLocale is specified on Locale Identifier:
[formatter setLocale:[[NSLocale alloc] initWithLocaleIdentifier:#"de_DE"]];
or use current local:
[formatter setLocale:[NSLocale currentLocale]];
Swift version
let formatter = NSNumberFormatter()
formatter.numberStyle = .DecimalStyle
formatter.maximumFractionDigits = decimalPlaces
let result = formatter.stringFromNumber(NSNumber(double: 8.0))
By http://ios.eezytutorials.com
An easy solution could be this. My answer is almost same like #Nazir's answer but with a small trick.
double current_balance = 2000000.00;
NSNumberFormatter * formatter = [NSNumberFormatter new];
[formatter setNumberStyle:NSNumberFormatterDecimalStyle];
//[formatter setNumberStyle:NSNumberFormatterCurrencyStyle]; //if you want for currency with $ sign
[formatter setMinimumFractionDigits:2]; // Set this if you need 2 digits
[formatter setMaximumFractionDigits:2]; // Set this if you need 2 digits
NSString * currency_format = [NSString stringWithFormat:#"%#", [formatter stringFromNumber:[NSNumber numberWithDouble:current_balance]]];
For Swift 4.0
let formatter = NumberFormatter()
formatter.numberStyle = .decimal
formatter.minimumFractionDigits = 2
formatter.maximumFractionDigits = 2
let result = formatter.string(from: NSNumber(value: 123456))
For those who need to do it with strings of numbers and not just integers (I.e. Big Numbers) I made the following macro:
#define addCommas(__string) (\
(^NSString *(void){\
NSString *__numberString = __string;\
NSString *__integerPortion = __numberString;\
NSString *__decimalPortion = #"";\
if ([__string containsString:#"."]) {\
__integerPortion = [__numberString componentsSeparatedByString:#"."][0];\
__decimalPortion = st(#".%#", [__numberString componentsSeparatedByString:#"."][1]);\
}\
int __i = (int)__integerPortion.length-3;\
while (__i > 0) {\
__integerPortion = st(#"%#,%#", substringInRange(__integerPortion, 0, __i), substringInRange(__integerPortion, __i, (int)__integerPortion.length));\
__i -= 3;\
}\
__numberString = st(#"%#%#", __integerPortion, __decimalPortion);\
return __numberString;\
})()\
)