NSNumberFormatter, appending decimal to calculator from UI - objective-c

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?

Related

How to get decimal values when the device is in french using NSNumber?

I have an issue with the textfield. This case works fine with the english language. However, if the device language is change to french (canada) , the textfield is not showing the values after the decimal.
For english:
I enter 99.99 and click Done. The text field display 99.99
For french:
I enter 99,99 and click Done . The text field display 99,00
Here is my code:
_amountField.text = [_amountField currencyFormatFromValue:[NSNumber numberWithDouble:_amountField.text.doubleValue]];
Here the [NSNumber numberWithDouble:_amountField.text.doubleValue] part is returning 99.99 in case of english and 99,00 in case of french
-(NSString *)currencyFormatFromValue:(NSNumber *)value{
NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
formatter.positiveFormat = #"###.00";
formatter.roundingMode = NSNumberFormatterRoundFloor;
[formatter setNumberStyle:NSNumberFormatterCurrencyStyle];
NSString *groupingSeparator = [[NSLocale currentLocale] objectForKey:NSLocaleGroupingSeparator];
[formatter setGroupingSeparator:groupingSeparator];
[formatter setUsesGroupingSeparator:YES];
[formatter setCurrencySymbol:#""];
[formatter setMinimumIntegerDigits:1];
NSString *formattedValue = [formatter stringFromNumber:value];
return formattedValue;
}
I am not sure, why the french text which is converted in double is terminating the decimal values. Any ideas?
Do I need to convert the text back to english before I sent the value to formatter?
I think your positiveFormat specification with the period is conflicting with NSNumberFormatterCurrencyStyle. I would try commenting out a bunch of lines and recompiling:
NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
// formatter.positiveFormat = #"###.00";
// formatter.roundingMode = NSNumberFormatterRoundFloor;
[formatter setNumberStyle:NSNumberFormatterCurrencyStyle];
// NSString *groupingSeparator = [[NSLocale currentLocale] objectForKey:NSLocaleGroupingSeparator];
// [formatter setGroupingSeparator:groupingSeparator];
// [formatter setUsesGroupingSeparator:YES];
// [formatter setCurrencySymbol:#""];
// [formatter setMinimumIntegerDigits:1];
NSString *formattedValue = [formatter stringFromNumber:value];
return formattedValue;
In my experience, the formatting out of the box will include grouping separator, currency symbols, rounding mode, etc. Specifying it again can potentially confuse the formatter.
If you really need to explicitly specify the positive format, you can try building the positive format string using the NSLocaleDecimalSeparator constant so that it will be a period or comma as required:
NSString *decimalSeparator = [[NSLocale currentLocale] objectForKey:NSLocaleDecimalSeparator];
formatter.positiveFormat = [NSString stringWithFormat:#"###%#00", decimalSeparator];
But I don't recommend it!
I found a way to make it work. I need to remove the , character in case of french that occur in the text field and send to formatter .
_amountField.text = [_amountField currencyFormatFromValue:[NSNumber numberWithDouble:[_amountField.text strippedAmount]doubleValue]];
and
//macro
#define IsFrenchLanguage() ([[[NSLocale preferredLanguages] objectAtIndex:0] rangeOfString:#"fr"].location != NSNotFound)
-(NSString *) strippedAmountString
{
NSString * thousandsSeparator = IsFrenchLanguage() ? #" " : #",";
return [self.amountField.text stringByReplacingOccurrencesOfString:thousandsSeparator withString:#""];
}

NSNumberFormatter: Displaying zero as last digit starting from a string like 25.0

I have a string that represents a float, for example 2400.0. I want to format it as digit (2,400.0) and I need to keep the zero after the digit symbol.
NSString* theString = #"2400.0";
// I convert the string to a float
float f = [theString floatValue];
// here I lose the digit information :( and it ends up with 2400 instead of 2400.0
NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
[formatter setNumberStyle:NSNumberFormatterDecimalStyle];
[formatter setUsesSignificantDigits:YES];
[formatter setMinimumFractionDigits:1];
[formatter setMaximumFractionDigits:2];
[formatter setLocale:[NSLocale currentLocale]];
NSString *result = [formatter stringFromNumber:#(f)];
The NSLog of result is 2,400 while I need 2,400.0
How can I obtain the right string?
You probably want to set the minimumFractionDigits to 1 (and your maximumFractionDigits as well in this case).
You also probably don't want to use significant digits. The following code yields the desired output:
NSString *theString = #"2400.0";
float f = [theString floatValue];
NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
[formatter setNumberStyle:NSNumberFormatterDecimalStyle];
[formatter setMinimumFractionDigits:1];
[formatter setMaximumFractionDigits:1];
[formatter setLocale:[NSLocale currentLocale]];
NSLog(#"%#", [formatter stringFromNumber:#(f)]);
Te below solves the issue
NSString *formatString = #"0,000.0";
[formatter setPositiveFormat:formatString];
The number of 0's after decimal will be used for formatting. It works for negative numbers also.
you should dynamically change the format string based on number of digits of the float value before and after decimal point.
Hope it helps.
easy,
then you go to display it just do this:
myLabel.text = #"%0.1f", f;
Use minimumFractionDigits in addition to maximumFractionDigits:
NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
formatter.minimumFractionDigits = 1;
formatter.maximumFractionDigits = 1;
XCTAssert([[formatter stringFromNumber:#(2400.0)] isEqualToString:#"2400.0"]);
XCTAssert([[formatter stringFromNumber:#(2400.1)] isEqualToString:#"2400.1"]);

Need Help Rounding Numbers (Float)

In the following code, I want the the number that satisfies if (isKgs) to be rounded to one decimal point.
For example right now it is giving me 2.2643534543 but I just want 2.3.
Any ideas?
NSNumber *weightInPounds = [self.pickerArray objectAtIndex:row];
NSNumber *weightInKilos = [[DDUnitConverter massUnitConverter] convertNumber: weightInPounds fromUnit: DDMassUnitUSPounds toUnit: DDMassUnitKilograms];
NSString *temp = [NSString stringWithFormat:#"%# kgs", [weightInKilos stringValue]];
[self.firstComponentText setString:temp];
The the type of number from the picker is float, I believe.
You can format the NSNumber object using an NSNumberFormatter object. An example,
NSNumber * decimal = [NSNumber numberWithFloat:2.2643534543];
NSNumberFormatter * formatter = [[NSNumberFormatter alloc] init];
[formatter setNumberStyle:NSNumberFormatterDecimalStyle];
[formatter setRoundingMode:NSNumberFormatterRoundHalfUp];
[formatter setMaximumFractionDigits:1];
NSLog(#"%#", [formatter stringFromNumber:decimal]);

Formatting a number to show commas and/or dollar sign

I want to format my UILabel with commas or better with a dollar sign and commas (with no decimal).
Here is the code I am using:
IBOutlet UILabel *labelrev
float rev = (x + y)
labelrev.text = [[NSString alloc] initWithFormat:#%2.f",rev];
I get xxxxxxxxx as the output I want to get xxx,xxx,xxx or $xxx,xxx,xxx
How do I do that?
You should definitely use NSNumberFormatter for this. The basic steps are:
Allocate, initialize and configure your number formatter.
Use the formatter to return a formatted string from a number. (It takes an NSNumber, so you'll need to convert your double or whatever primitive you have to NSNumber.)
Clean up. (You know, memory management.)
This code sets up the number formatter. I've done everything that you want except the currency bit. You can look that up in the documentation.
NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
[formatter setNumberStyle:NSNumberFormatterCurrencyStyle];
NSString *groupingSeparator = [[NSLocale currentLocale] objectForKey:NSLocaleGroupingSeparator];
[formatter setGroupingSeparator:groupingSeparator];
[formatter setGroupingSize:3];
[formatter setAlwaysShowsDecimalSeparator:NO];
[formatter setUsesGroupingSeparator:YES];
Next, you want to set up your number and return a formatted string. In your case, we wrap a double in an NSNumber. I do it inline, but you can break it up into two steps:
NSString *formattedString = [formatter stringFromNumber:[NSNumber numberWithFloat:rev];
Don't forget to clean up!
[formatter release];
A quick note about localization:
The NSLocale class provides some useful info about the user's locale. In the first step, notice how I used NSLocale to get a localized grouping separator:
NSString *groupingSeparator = [[NSLocale currentLocale] objectForKey:NSLocaleGroupingSeparator];
(Some countries use a full-stop/period, while others use a comma.) I think there's a way to get a localized currency symbol as well, but I'm not one hundred percent sure, so check the documentation. (It depends upon what your trying to do.)
You will need to use a NSNumberFormatter which supports currency.
NSNumberFormatter *currencyFormatter = [[NSNumberFormatter alloc] init];
[currencyFormatter setNumberStyle:NSNumberFormatterCurrencyStyle];
NSLog(#"%#", [currencyFormatter stringFromNumber:[NSNumber numberWithInt:10395209]]);
[currencyFormatter release];
Prints: $10,395,209.00
[formatterCurrency setMaximumFractionDigits:0]
is only way to trancate decimal digits and decimal separator in a NSNumberFormatterCurrencyStyle formatter.
NSNumberFormatter *formatterCurrency;
formatterCurrency = [[NSNumberFormatter alloc] init];
formatterCurrency.numberStyle = NSNumberFormatterCurrencyStyle;
[formatterCurrency setMaximumFractionDigits:0];
[formatterCurrency stringFromNumber: #(12345.2324565)];
result
12,345 $

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;\
})()\
)