NSNumberFormatter currency remove trailing zeros - objective-c

I want to format prices like 45.50 but I don't want prices like 45.00. How can I avoid this?

I did it this way:
NSNumber *amount = #(50.5);
NSNumberFormatter *currencyFormat = [[NSNumberFormatter alloc] init];
[currencyFormat setNumberStyle:NSNumberFormatterCurrencyStyle];
[currencyFormat setLocale:[NSLocale currentLocale]];
if (trunc(amount.floatValue) == amount.floatValue) {
[currencyFormat setMaximumFractionDigits:0];
} else {
[currencyFormat setMaximumFractionDigits:2];
}
NSLog(#"%#", [currencyFormat stringFromNumber:amount]);
I like this solution for its simplicity. Output will be $50.50. And for amount = #(50.0) will be $50

Do this:
NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
[formatter setNumberStyle:NSNumberFormatterDecimalStyle];
[formatter setMaximumFractionDigits:2];
[formatter setRoundingMode: NSNumberFormatterRoundUp];
NSString *numberString = [formatter stringFromNumber:[NSNumber numberWithFloat:22.368511]];
NSLog(#"Result...%#",numberString);//Result 22.37
Now trail unwanted like this:
NSString* CWDoubleToStringWithMax2Decimals(double d) {
NSString* s = [NSString stringWithFormat:#"%.2f", d];
NSCharacterSet* cs = [NSCharacterSet characterSetWithCharacterInString:#"0."];
NSRange r = [s rangeOfCharacterInSet:cs
options:NSBackwardsSearch | NSAnchoredSearch];
if (r.location != NSNotFound) {
s = [s substringToIndex:r.location];
}
return s;
}

If you're just after a very quick and dirty hack . . .
// Get the price as a string
NSString *priceString = [NSString stringWithFormat:#"%2.2f", priceFloat];
// Trim if needed
if ([priceString hasSuffix:#".00"])
priceString = [priceString substringToIndex:priceString.length-3];
NB This method won't work for localised content i.e. In Europe the decimal separator is a comma so you will see 45,00, not 45.00.

float myOriginalPrice = 45.50;
CGFloat mod = fmod(myOriginalPrice, 1);
if (mod == 0){
mod = (int)myOriginalPrice;
NSLog(#"%.0f", mod);
} else {
NSLog(#"%f", myOriginalPrice);
}

INPUT : 12.74 OR 12.745
NSString *inputString=[NSString string];
inputString=[NSString stringWithFormat:#"%.4g",12.74f];
NSLog(#"inputString : %# \n\n",inputString);
OUTPUT:
inputString : 12.74
INPUT : 12.00 OR 12.000
NSString *inputString=[NSString string];
inputString=[NSString stringWithFormat:#"%.4g",12.00f];
NSLog(#"inputString : %# \n\n",inputString);
OUTPUT:
inputString : 12
UPDATED ANSWER: for his comment question
INPUT:12.30
i assume here he is going to show this value in some UI like UILabel,.....Not For Calculation.
NSString *inputString=[NSString string];
inputString=[NSString stringWithFormat:#"%.4g",12.30f];
NSArray *arr=[inputString componentsSeparatedByString:#"."];
if ([arr count] >= 2) {
NSString *secondStr=[arr objectAtIndex:1];
if ([secondStr length]<2) {
inputString=[NSString stringWithFormat:#"%#0",inputString];
}
}
NSLog(#"inputString : %# \n\n",inputString);
OUTPUT:
inputString : 12.30

Related

how to convert arabic number to english number

I could convert English numbers to Arabic numbers in Xcode. but now I want to convert Arabic/Persian numbers to English numbers in iOS ...
Please guide me about this...
This is my code for conversion (English to Arabic) :
- (NSString*)convertEnNumberToFarsi:(NSString*)number {
NSString *text;
NSDecimalNumber *someNumber = [NSDecimalNumber decimalNumberWithString:number];
NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
NSLocale *gbLocale = [[NSLocale alloc] initWithLocaleIdentifier:#"fa"];
[formatter setLocale:gbLocale];
text = [formatter stringFromNumber:someNumber];
return text;
}
Try this, I hope this helps you :
NSString *NumberString = #"۸۸۸";
NSNumberFormatter *Formatter = [[NSNumberFormatter alloc] init];
NSLocale *locale = [NSLocale localeWithLocaleIdentifier:#"EN"];
[Formatter setLocale:locale];
NSNumber *newNum = [Formatter numberFromString:NumberString];
if (newNum) {
NSLog(#"%#", newNum);
}
//print in console 888
You must take care of not only Persian numbers, but also Arabic ones.
Use the below functions/methods to do so:
// Convert string From English numbers to Persian numbers
+(NSString *) convertToPersianNumber:(NSString *) string {
NSNumberFormatter *formatter = [NSNumberFormatter new];
formatter.locale = [NSLocale localeWithLocaleIdentifier:#"fa"];
for (NSInteger i = 0; i < 10; i++) {
NSNumber *num = #(i);
string = [string stringByReplacingOccurrencesOfString:num.stringValue withString:[formatter stringFromNumber:num]];
}
return string;
}
// Convert string From Arabic/Persian numbers to English numbers
+(NSString *) convertToEnglishNumber:(NSString *) string {
NSNumberFormatter *formatter = [NSNumberFormatter new];
formatter.locale = [NSLocale localeWithLocaleIdentifier:#"fa"];
for (NSInteger i = 0; i < 10; i++) {
NSNumber *num = #(i);
string = [string stringByReplacingOccurrencesOfString:[formatter stringFromNumber:num] withString:num.stringValue];
}
formatter.locale = [NSLocale localeWithLocaleIdentifier:#"ar"];
for (NSInteger i = 0; i < 10; i++) {
NSNumber *num = #(i);
string = [string stringByReplacingOccurrencesOfString:[formatter stringFromNumber:num] withString:num.stringValue];
}
return string;
}
Follow the same. Just replace your locale identifier with "en".

NSNumberFormatter unable to allow numbers to start with a 0

So I'm attempting to automatically add slashes between 2 digits when a user enters in their birthday, but for some reason when the birthday starts with a 0, the number formatter erases it and messes up the birthday. I've got my code below, could someone help me figure out how to do this? Thanks in advance!
NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init] ;
[formatter setGroupingSeparator:#"/"];
[formatter setGroupingSize:2];
[formatter setUsesGroupingSeparator:YES];
[formatter setSecondaryGroupingSize:2];
NSString *num = textField.text ;
if(![num isEqualToString:#""])
{
num= [num stringByReplacingOccurrencesOfString:#"/" withString:#""];
NSString *str = [formatter stringFromNumber:[NSNumber numberWithDouble:[num doubleValue]]];
textField.text=str;
}
What you could do is the following:
Check the length of the string
If length mod 2 == 0 then add "/"
Log your string
I'm not saying this is recommended but it might help you a bit!
- (void)controlTextDidChange:(NSNotification *)obj{
NSString *num = [textField stringValue] ;
if (num.length%2==0)
{
NSString *someText = [NSString stringWithFormat: #"%#/ ", num];
num = someText;
}
textField.stringValue = num;
}
Something like this may help:
NSMutableString *string = #"YOUR TEXTFIELD TEXT";
NSString *lastString = [string substringWithRange:NSMakeRange(string.length-2, 1)];
if ([lastString isEqualToString:#"/"]) {
return;
}
if (string.length == 2 || string.length == 5) {
[string appendString:#"/"];
}

How can i display the number in such a format?

I am displaying a number in textfield. Which displays the number as "1234" but i want to display it as in format of "1,234" if i enter another large number which displays as "12345" but i want to display it as "12,345" if i enter 123456 which has to display as "123,456" . How do I format this number in desired format?
-(void)clickDigit:(id)sender
{
NSString * str = (NSString *)[sender currentTitle];
NSLog(#"%#",currentVal);
if([str isEqualToString:#"."]&& !([currentVal rangeOfString:#"."].location == NSNotFound) )
{
return;
}
if ([display.text isEqualToString:#"0"])
{
currentVal = str;
[display setText:currentVal];
}
else if([currentVal isEqualToString:#"0"])
{
currentVal=str;
[display setText:currentVal];
}
else
{
if ([display.text length] <= MAXLENGTH)
{
currentVal = [currentVal stringByAppendingString:str];
NSLog(#"%#",currentVal);
[display setText:currentVal];
}
currentVal=display.text;
}
}
This is the code i am using to display the number in textfield.
EDIT: I Changed my code into the following but still don't get the number correctly formatted:
if ([display.text length] <= MAXLENGTH) {
currentVal = [currentVal stringByAppendingString:str];
NSNumberFormatter * myNumFormatter = [[NSNumberFormatter alloc] init];
[myNumFormatter setNumberStyle:NSNumberFormatterDecimalStyle];
NSNumber *tempNum = [myNumFormatter numberFromString:currentVal];
NSLog(#"My number is %#",tempNum);
[display setText:[tempNum stringValue]];
currentVal=display.text;
}
You can do it like this:
int myInt = 12345;
NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
formatter.numberStyle = NSNumberFormatterDecimalStyle;
NSNumber *number = [NSNumber numberWithInt:myInt];
NSLog(#"%#", [formatter stringFromNumber:number]); // 12,345
Edit
You didn't implement this correctly, the key is to obtain the string representation of the number using [formatter stringFromNumber:number], but you didn't do that. So change your code into:
currentVal = [currentVal stringByAppendingString:str];
NSNumberFormatter * myNumFormatter = [[NSNumberFormatter alloc] init];
[myNumFormatter setNumberStyle:NSNumberFormatterDecimalStyle];
NSNumber *tempNum = [myNumFormatter numberFromString:currentVal];
NSLog(#"My number is %#",tempNum);
[display setText:[myNumFormatter stringFromNumber:tempNum]]; // Change this line
currentVal=display.text;
NSLog(#"My formatted number is %#", currentVal);
First, read through the list of methods on the NSNumberFormatter reference page. After doing that, you'll probably realize that you need to use the -setHasThousandSeparators: method to turn on the thousand separators feature. You can also use the -setThousandSeparator: method to set a custom separator, though you probably won't need to do that.

Truncate extra zeroes when formatting a float into an NSString

I am trying to format some floats as follows:
1.1500 would be displayed as “$ 1.15”
1.1000 would be displayed as “$ 1.10”
1.0000 would be displayed as “$ 1.00”
1.4710 would be displayed as “$ 1.471”
1.4711 would be displayed as “$ 1.4711”
I tried with
NSString *answer = [NSString stringWithFormat:#"$ %.2f",myvalue];
This is exactly what NSNumberFormatters are for:
float onefifteen = 1.1500; // displayed as “$ 1.15”
float oneten = 1.1000; // displayed as “$ 1.10”
float one = 1.0000; // displayed as “$ 1.00”
float onefortyseventen = 1.4710; // displayed as “$ 1.471”
float onefortyseveneleven = 1.4711; // displayed as “$ 1.4711”
NSNumberFormatter * formatter = [[NSNumberFormatter alloc] init];
[formatter setNumberStyle:NSNumberFormatterCurrencyStyle];
[formatter setUsesSignificantDigits:YES];
// The whole number counts as the first "significant digit"
[formatter setMinimumSignificantDigits:3];
NSLog(#"%#", [formatter stringFromNumber:[NSNumber numberWithFloat:onefifteen]]);
NSLog(#"%#", [formatter stringFromNumber:[NSNumber numberWithFloat:oneten]]);
NSLog(#"%#", [formatter stringFromNumber:[NSNumber numberWithFloat:one]]);
NSLog(#"%#", [formatter stringFromNumber:[NSNumber numberWithFloat:onefortyseventen]]);
NSLog(#"%#", [formatter stringFromNumber:[NSNumber numberWithFloat:onefortyseveneleven]]);
2011-12-15 19:36:52.185 SignificantCents[49282:903] $1.15
2011-12-15 19:36:52.190 SignificantCents[49282:903] $1.10
2011-12-15 19:36:52.190 SignificantCents[49282:903] $1.00
2011-12-15 19:36:52.191 SignificantCents[49282:903] $1.471
2011-12-15 19:36:52.192 SignificantCents[49282:903] $1.4711
try this :
NSString *answer = [NSString stringWithFormat:#"%.02f", myvalue];
I have figure out this. you can do this as per below implementation.
Please take a look at below demo code...
NSArray * numbers = [[NSArray alloc] initWithObjects:#"1.1500",#"1.1000",#"1.0000",#"1.4710",#"1.4711",nil];
for (int i=0; i<[numbers count]; i++) {
NSArray * floatingPoint = [[numbers objectAtIndex:i] componentsSeparatedByString:#"."];
NSString * lastObject = [[floatingPoint lastObject] stringByReplacingOccurrencesOfString:#"0" withString:#""];
if ([lastObject length] < 2) {
NSLog(#"%#",[NSString stringWithFormat:#"$ %.2f",[[numbers objectAtIndex:i] floatValue]]);
} else {
NSLog(#"%#",[NSString stringWithFormat:#"$ %g",[[numbers objectAtIndex:i] floatValue]]);
}
}
Thanks,
MinuMaster
Read the docs on format specifiers.

Convert basic script to Objective C (money formatting)

I've got this basic like script that I need to convert to objective c, it turns big units of money into shortened versions (ie: 1.2m, etc), I've got most of the conversion done, but the biggest problem I'm having is right at the end.
The original basic code is:
; Basic Code
Function ShortCash$(BigNumber)
out$=""
; First, grab the length of the number
L=Len(BigNumber)
Letter$=""
;Next, Do a sweep of the values, and cut them down.
If l<13
out$=(BigNumber/1000000000)
; For each figure, out remainder should be divided so that it leaves a 2 digit decimal number..
remainder=(BigNumber Mod 1000000000)/10000000
; And we also want a letter to symbolise our large amounts..
Letter$="b" ; BILLION!!!!
EndIf
If l<10 Then out$=(BigNumber/1000000):remainder=(BigNumber Mod 1000000)/10000:Letter$="m"
If l<7 Then out$=(BigNumber/1000):remainder=(BigNumber Mod 1000)/10:Letter$="k"
If l<4 Then out$=BigNumber:remainder=0:Letter$=""
;Next, if remainder=0 then we're happy.. ie, £1m is fine, we need no decimal.
;But, if the remainder is >0 we'll want a nice rounded 2 decimal number, instead.
If remainder>0
out$=out$+"."+Right$("00"+remainder,2) ; Last two numbers..
; Additionally, if the rightmost figure is a 0, remove it.
; (ie, if the value is 1.50, we don't need the 0)
If Right$(out$,1)="0" Then out$=Left$(out$,Len(out$)-1)
EndIf
; And throw on our letter, at the end.
out$=out$+letter$
Return out$
End Function
// The following was edited on Thur 5 Aug by Author of post.
I believe I've got it sorted now, I've got the following to work for thousands for the moment, I'm not sure if it will work under all circumstances and would welcome any help/guidance on this. I am aware of the memory issues, I'll sort that out later, its the string manipulation part I am resolving first.
// This goes inside the (IBAction) update method;
NSNumber *bigNumber = nil;
if ( [inputField.text length] >0)
{
bigNumber = [NSNumber numberWithInt:[inputField.text intValue]];
}
int bigNumberAsInt = [bigNumber intValue];
NSString *bigNumberAsString = [bigNumber stringValue];
int bigNumberStrLen = [bigNumberAsString length];
NSLog(#"bigNumber = %#", bigNumber);
//NSLog(#"bigNumberAsString = %#", bigNumberAsString);
NSLog(#"bigNumberStrLen = %d", bigNumberStrLen);
NSLog(#"=========");
// =========
NSNumberFormatter *nformat = [[[NSNumberFormatter alloc] init] autorelease];
[nformat setFormatterBehavior:NSNumberFormatterBehavior10_4];
[nformat setCurrencySymbol:#"$"];
[nformat setNumberStyle:NSNumberFormatterCurrencyStyle];
[nformat setMaximumFractionDigits:0];
NSLog(#"Cash = %#", [nformat stringFromNumber:bigNumber]);
// =========
NSString *output = [[NSString alloc] init];
NSString *letter;
// ==========
// Anything less than 1m represent with a k
if (bigNumberStrLen < 7)
{
letter = #"k";
int sum = (bigNumberAsInt / 1000);
int int_remainder = ((bigNumberAsInt % 1000) / 10);
NSLog(#"Remainder = %d", int_remainder);
NSString *sumAsString = [NSString stringWithFormat:#"%d", sum];
NSString *remainderAsString = [NSString stringWithFormat:#"%d", int_remainder];
NSLog(#"Sum as String = %#", sumAsString);
NSLog(#"Remainder as String = %#", remainderAsString);
if (int_remainder >0)
{
NSLog(#"Remainder > 0");
output = [output stringByAppendingString:sumAsString];
output = [output stringByAppendingString:#"."];
output = [output stringByAppendingString:remainderAsString];
NSLog(#"Output = %#", output);
NSUInteger outputStrLen = [output length];
NSLog(#"Output strlen = %d", outputStrLen);
if ([output hasSuffix:#"0"])
{
NSLog(#"Has suffix of 0");
// Remove suffix
output = [output substringWithRange: NSMakeRange(0, outputStrLen-1)];
}
}
output = [output stringByAppendingString:letter];
NSLog(#"Final output = %#", output);
}
This will display 10.2k (if it ends with a 0 suffix) or it will display 10.2x where X is the last number.
Can someone just double check this, or perhaps there's an easier way to do all this. In either case, thanks for your help.
Just to improve the solution, a good idea is maybe to subclass the NSNumberFormatter class and override the - (NSString *)stringForObjectValue:(id)anObject method.
Using the code from zardon, I added a statement for the values < 1000 which doesn't format the number.
Here is the code of the method :
/*
Override the stringForObjectValue method from NSNumberFormatter
100 -> 100
1000 -> 1k
1 000 000 -> 1m
1 000 000 000 -> 1b
1 000 000 000 -> 1t
*/
- (NSString *)stringForObjectValue:(id)anObject {
// If we don't get a NSNumber, we can't create the string
if (![anObject isKindOfClass:[NSNumber class]]) {
return nil;
}
NSNumberFormatter *nformat = [[NSNumberFormatter alloc] init];
// Decimal value from the NSObject
double doubleValue = [anObject doubleValue];
NSString *stringValue = nil;
// Abbrevations used
NSArray *abbrevations = [NSArray arrayWithObjects:#"k", #"m", #"b", #"t", nil] ;
// If the value is less than 1000, we display directly the value
if(doubleValue < 1000.0) {
stringValue = [NSString stringWithFormat: #"%#", [nformat stringFromNumber: [NSNumber numberWithDouble: doubleValue]] ];
}
else { // Otherwise we format it as expected
for (NSString *s in abbrevations) {
doubleValue /= 1000.0 ;
if ( doubleValue < 1000.0 ) {
if ( (long long)doubleValue % (long long) 100 == 0 ) {
[nformat setMaximumFractionDigits:0];
} else {
[nformat setMaximumFractionDigits:2];
}
stringValue = [NSString stringWithFormat: #"%#", [nformat stringFromNumber: [NSNumber numberWithDouble: doubleValue]] ];
NSUInteger stringLen = [stringValue length];
if ( [stringValue hasSuffix:#".00"] )
{
// Remove suffix
stringValue = [stringValue substringWithRange: NSMakeRange(0, stringLen-3)];
} else if ( [stringValue hasSuffix:#".0"] ) {
// Remove suffix
stringValue = [stringValue substringWithRange: NSMakeRange(0, stringLen-2)];
} else if ( [stringValue hasSuffix:#"0"] ) {
// Remove suffix
stringValue = [stringValue substringWithRange: NSMakeRange(0, stringLen-1)];
}
// Add the letter suffix at the end of it
stringValue = [stringValue stringByAppendingString: s];
break;
}
}
}
[nformat release];
return stringValue;
}
In the interface we simply add the inheritage statement :
#interface MoneyNumberFormatter : NSNumberFormatter
Hope this helps..
.... Okay, with thanks to the author of the Cocoa Tidbits blog, I believe I have a solution which is much more elegant, faster and doesn't require so much coding; it still needs testing, and it also probably requires a little more editing, but it seems to be much better than my original.
I modified the script a little to make it not show any trailing zeros where relevant;
NSNumberFormatter *nformat = [[NSNumberFormatter alloc] init];
[nformat setFormatterBehavior:NSNumberFormatterBehavior10_4];
[nformat setCurrencySymbol:#"$"];
[nformat setNumberStyle:NSNumberFormatterCurrencyStyle];
double doubleValue = 10200;
NSString *stringValue = nil;
NSArray *abbrevations = [NSArray arrayWithObjects:#"k", #"m", #"b", #"t", nil] ;
for (NSString *s in abbrevations)
{
doubleValue /= 1000.0 ;
if ( doubleValue < 1000.0 )
{
if ( (long long)doubleValue % (long long) 100 == 0 ) {
[nformat setMaximumFractionDigits:0];
} else {
[nformat setMaximumFractionDigits:2];
}
stringValue = [NSString stringWithFormat: #"%#", [nformat stringFromNumber: [NSNumber numberWithDouble: doubleValue]] ];
NSUInteger stringLen = [stringValue length];
if ( [stringValue hasSuffix:#".00"] )
{
// Remove suffix
stringValue = [stringValue substringWithRange: NSMakeRange(0, stringLen-3)];
} else if ( [stringValue hasSuffix:#".0"] ) {
// Remove suffix
stringValue = [stringValue substringWithRange: NSMakeRange(0, stringLen-2)];
} else if ( [stringValue hasSuffix:#"0"] ) {
// Remove suffix
stringValue = [stringValue substringWithRange: NSMakeRange(0, stringLen-1)];
}
// Add the letter suffix at the end of it
stringValue = [stringValue stringByAppendingString: s];
//stringValue = [NSString stringWithFormat: #"%#%#", [nformat stringFromNumber: [NSNumber numberWithDouble: doubleValue]] , s] ;
break ;
}
}
NSLog(#"Cash = %#", stringValue);