I have the value 25.00 in a float, but when I print it on screen it is 25.0000000.
How can I display the value with only two decimal places?
It is not a matter of how the number is stored, it is a matter of how you are displaying it. When converting it to a string you must round to the desired precision, which in your case is two decimal places.
E.g.:
NSString* formattedNumber = [NSString stringWithFormat:#"%.02f", myFloat];
%.02f tells the formatter that you will be formatting a float (%f) and, that should be rounded to two places, and should be padded with 0s.
E.g.:
%f = 25.000000
%.f = 25
%.02f = 25.00
Here are few corrections-
//for 3145.559706
Swift 3
let num: CGFloat = 3145.559706
print(String(format: "%f", num)) = 3145.559706
print(String(format: "%.f", num)) = 3145
print(String(format: "%.1f", num)) = 3145.6
print(String(format: "%.2f", num)) = 3145.56
print(String(format: "%.02f", num)) = 3145.56 // which is equal to #"%.2f"
print(String(format: "%.3f", num)) = 3145.560
print(String(format: "%.03f", num)) = 3145.560 // which is equal to #"%.3f"
Obj-C
#"%f" = 3145.559706
#"%.f" = 3146
#"%.1f" = 3145.6
#"%.2f" = 3145.56
#"%.02f" = 3145.56 // which is equal to #"%.2f"
#"%.3f" = 3145.560
#"%.03f" = 3145.560 // which is equal to #"%.3f"
and so on...
You can also try using NSNumberFormatter:
NSNumberFormatter* nf = [[[NSNumberFormatter alloc] init] autorelease];
nf.positiveFormat = #"0.##";
NSString* s = [nf stringFromNumber: [NSNumber numberWithFloat: myFloat]];
You may need to also set the negative format, but I think it's smart enough to figure it out.
I made a swift extension based on above answers
extension Float {
func round(decimalPlace:Int)->Float{
let format = NSString(format: "%%.%if", decimalPlace)
let string = NSString(format: format, self)
return Float(atof(string.UTF8String))
}
}
usage:
let floatOne:Float = 3.1415926
let floatTwo:Float = 3.1425934
print(floatOne.round(2) == floatTwo.round(2))
// should be true
In Swift Language, if you want to show you need to use it in this way. To assign double value in UITextView, for example:
let result = 23.954893
resultTextView.text = NSString(format:"%.2f", result)
If you want to show in LOG like as objective-c does using NSLog(), then in Swift Language you can do this way:
println(NSString(format:"%.2f", result))
IN objective-c, if you are dealing with regular char arrays (instead of pointers to NSString) you could also use:
printf("%.02f", your_float_var);
OTOH, if what you want is to store that value on a char array you could use:
sprintf(your_char_ptr, "%.02f", your_float_var);
The problem with all the answers is that multiplying and then dividing results in precision issues because you used division. I learned this long ago from programming on a PDP8.
The way to resolve this is:
return roundf(number * 100) * .01;
Thus 15.6578 returns just 15.66 and not 15.6578999 or something unintended like that.
What level of precision you want is up to you. Just don't divide the product, multiply it by the decimal equivalent.
No funny String conversion required.
in objective -c is u want to display float value in 2 decimal number then pass argument indicating how many decimal points u want to display
e.g 0.02f will print 25.00
0.002f will print 25.000
Here's some methods to format dynamically according to a precision:
+ (NSNumber *)numberFromString:(NSString *)string
{
if (string.length) {
NSNumberFormatter * f = [[NSNumberFormatter alloc] init];
f.numberStyle = NSNumberFormatterDecimalStyle;
return [f numberFromString:string];
} else {
return nil;
}
}
+ (NSString *)stringByFormattingString:(NSString *)string toPrecision:(NSInteger)precision
{
NSNumber *numberValue = [self numberFromString:string];
if (numberValue) {
NSString *formatString = [NSString stringWithFormat:#"%%.%ldf", (long)precision];
return [NSString stringWithFormat:formatString, numberValue.floatValue];
} else {
/* return original string */
return string;
}
}
e.g.
[TSPAppDelegate stringByFormattingString:#"2.346324" toPrecision:4];
=> 2.3453
[TSPAppDelegate stringByFormattingString:#"2.346324" toPrecision:0];
=> 2
[TSPAppDelegate stringByFormattingString:#"2.346324" toPrecision:2];
=> 2.35 (round up)
Another method for Swift (without using NSString):
let percentage = 33.3333
let text = String.localizedStringWithFormat("%.02f %#", percentage, "%")
P.S. this solution is not working with CGFloat type only tested with Float & Double
Use NSNumberFormatter with maximumFractionDigits as below:
NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
formatter.maximumFractionDigits = 2;
NSLog(#"%#", [formatter stringFromNumber:[NSNumber numberWithFloat:12.345]]);
And you will get 12.35
If you need to float value as well:
NSString* formattedNumber = [NSString stringWithFormat:#"%.02f", myFloat];
float floatTwoDecimalDigits = atof([formattedNumber UTF8String]);
lblMeter.text=[NSString stringWithFormat:#"%.02f",[[dic objectForKey:#"distance"] floatValue]];
Related
I am using StoreKit to implement an in app purchase store in my application.
I have a custom design and it means that the value of the price should be white and large, and the currency symbol smaller, darker and aligned to the top of the price value.
I can get the currency symbol without any problems by using the NSLocale in SKproduct's priceLocale property, and the value of the price in the price property.
My problem is knowing when I should put the currency symbol before the price and when to put it after the price.
Examples:
$5,99
0,79€
I could easily use the NSNumberFormatter to get this worked out "out of the box", but since my layout defines a different style for the value and currency symbol, I've found myself in a position where a more manual workaround is required.
Any thoughts ?
You have everything you need in your SKProduct instance. Just use NSNumberFormatter in conjunction and that's it.
NSNumberFormatter *priceFormatter = [[NSNumberFormatter alloc] init];
[priceFormatter setNumberStyle:NSNumberFormatterCurrencyStyle];
for (SKProduct *product in response.products) {
[priceFormatter setLocale:product.priceLocale];
NSLog(#"Price for %# is: %#",product.localizedTitle,[priceFormatter stringFromNumber:product.price]);
}
Swift 3+
let priceFormatter = NumberFormatter()
priceFormatter.numberStyle = .currency
for product in response.products {
priceFormatter.locale = product.priceLocale
let localizedPrice = priceFormatter.string(from: product.price)
print("Price for \(product.localizedTitle) is: \(localizedPrice)")
}
The locale object doesn't seem to provide this information directly, but of course the number formatter must know it. You're not supposed to ask (new-style) number formatters for their format directly, although that'll probably work, and you can then look for the currency symbol, ¤, in the format string.
Possibly better would be to create a CFNumberFormatter, which does explicitly allow you to view its format, and then inspect that string:
// NSLocale and CFLocale are toll-free bridged, so if you have an existing
// NSNumberFormatter, you can get its locale and use that instead.
CFLocaleRef usLocale = CFLocaleCreate(NULL, CFSTR("en_US"));
CFNumberFormatterRef usFormatter = CFNumberFormatterCreate(NULL, usLocale, kCFNumberFormatterCurrencyStyle);
CFLocaleRef frLocale = CFLocaleCreate(NULL, CFSTR("fr_FR"));
CFNumberFormatterRef frFormatter = CFNumberFormatterCreate(NULL, frLocale, kCFNumberFormatterCurrencyStyle);
NSString * usString = (__bridge NSString *)CFNumberFormatterGetFormat(usFormatter);
NSString * frString = (__bridge NSString *)CFNumberFormatterGetFormat(frFormatter);
NSUInteger loc = ([usString rangeOfString:#"¤"]).location;
NSLog(#"Currency marker at beginning for US? %#", (loc == 0) ? #"YES" : #"NO");
loc = ([frString rangeOfString:#"¤"]).location;
NSLog(#"Currency marker at end for FR? %#", (loc == [frString length] - 1) ? #"YES" : #"NO");
I use this solution (Swift):
let currencyFormat = CFNumberFormatterGetFormat(CFNumberFormatterCreate(nil, locale, .CurrencyStyle)) as NSString
let positiveNumberFormat = currencyFormat.componentsSeparatedByString(";")[0] as NSString
let currencySymbolLocation = positiveNumberFormat.rangeOfString("¤").location
return (currencySymbolLocation == 0) ? .Before : .After
The accepted answer should be fixed since the CFNumberFormatterGetFormat sometimes (for some locales) returns double value: ¤##,#00.0;-¤##,#00.0 which includes a negative number format. Make sure to parse that string.
My solution for this was to set the decimal style and set the minimum number of significant digits.
static NSNumberFormatter *NumberFormatter;
if (!NumberFormatter) {
NumberFormatter = [[NSNumberFormatter alloc] init];
[NumberFormatter setNumberStyle:NSNumberFormatterDecimalStyle];
[NumberFormatter setUsesSignificantDigits:YES];
[NumberFormatter setMinimumSignificantDigits:2];
}
NSString *formattedNumberString = [NumberFormatter stringFromNumber:#(valueInEuro)];
NSString *stringInEuro = [NSString stringWithFormat:#"€ %#", formattedNumberString];
I have created an extension of SKProduct, putting things where they belong imho.
extension SKProduct
{
var localizedPrice: String {
let numberFormatter = NSNumberFormatter()
numberFormatter.numberStyle = .CurrencyStyle
numberFormatter.locale = self.priceLocale
numberFormatter.formatterBehavior = .Behavior10_4
return numberFormatter.stringFromNumber(self.price)!
}
}
That way of formatting is, by the way, also exactly what Apple suggests in the In-App Purchase Programming Guide, section Retrieving Product Information.
Swift 3
An extension function on Locale:
extension Locale {
func IsCurrenySymbolAtStart() -> Bool {
let currencyFormatter = NumberFormatter()
currencyFormatter.numberStyle = .currency
currencyFormatter.locale = self
let positiveFormat = currencyFormatter.positiveFormat as NSString
let currencySymbolLocation = positiveFormat.range(of: "¤").location
return (currencySymbolLocation == 0)
}
}
Usage:
let displayCurrencySymbolAtStart = NSLocale.current.IsCurrenySymbolAtStart()
I am trying to trim zeros after a decimal point as below but it's not giving desired result.
trig = [currentVal doubleValue];
trig = trig/100;
NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
[formatter setMaximumFractionDigits:0];
display.text = [formatter stringFromNumber:[NSNumber numberWithDouble:trig]];
The number is still being displayed without trimming zeros after the decimal point.
Here currentVal is the number I am entering.
For example if i pass "trig" = 123 (Initially "trig" = 123 after doing trig/100 i want to display 1.23 but it is displaying as 1.23000000).
Sometimes the straight C format specifiers do an easier job than the Cocoa formatter classes, and they can be used in the format string for the normal stringWithFormat: message to NSString.
If your requirement is to not show any trailing zeroes, then the "g" format specifier does the job:
float y = 1234.56789f;
NSString *s = [NSString stringWithFormat:#"%g", y];
Notice that there is no precision information, which means that the printf library will remove the trailing zeroes itself.
There is more information in the docs, which refer to IEEE's docs.
In case this helps someone. I wanted 1 decimal value but no '.0' on the end if the float was '1.0'. Using %g would give scientific notation for longer numbers, following ugliness worked well enough for me as high accuracy wasn't critical.
// Convert to 1 dp string,
NSString* dirtyString = [NSString stringWithFormat: #"%.1f", self.myFloat];
// Convert back to float that is now a maximum of 1 dp,
float myDirtyFloat = [dirtyString floatValue];
// Output the float subtracting the zeros the previous step attached
return [NSString stringWithFormat: #"%g", myDirtyFloat];
This will not display any decimal value after the decimal point:
display.text = [NSString stringWithFormat:#"%1.0f", trig];
This will just trim the zeros after the decimal point:
isplay.text = [NSString stringWithFormat:#"%3.2f", trig];
display.text = [display.text stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:[NSString stringWithFormat#"0"]]];
Note, this may leave you with the trailing decimal point. "124." may happen. I guess that some smarter solution will be posted soon.
From the documentation, it looks like setFractionDigits: is only for converting the other way.
The best thing to do is probably to convert your number to an integer before formatting it e.g.
double converted = round(trig); // man round for docs
You can use also the formatting functions of stringWithFormat: of NSString, but then you will lose all the localisation advantages you get with NSNumberFormatter.
This may not be a proper solution where there is NSNumberFormetter Class, But I just did this rather then googling a lot! ;)
Here is an example, if it helps:
-(NSString*) trimZerosAfterDecimalPoint:(NSString*)string_ {
double doubleValue=[string_ doubleValue];
long leftPart=(long)doubleValue;
double rightPart=doubleValue-(double)leftPart;
NSString *rightPartAsStr=[NSString stringWithFormat:#"%f", rightPart];
int i=0;
for (i=rightPartAsStr.length-1; i>=2; i--) {
if ([rightPartAsStr characterAtIndex:i]!='0') {
rightPartAsStr=[rightPartAsStr substringWithRange:NSMakeRange(2, i-1)];
break;
}
}
if (i<2) {
string_=[NSString stringWithFormat:#"%ld", leftPart];
} else {
string_=[NSString stringWithFormat:#"%ld.%#", leftPart, rightPartAsStr];
}
return string_;
}
I just had to do this for one of my programs and heres how I went about it:
- (void) simplify{
int length = (int)[self.calcString length];
for (int i = (int)[self.calcString length]; i > 0; i--) {
if ([self.calcString rangeOfString:#"."].location != NSNotFound) {
NSRange prevChar = NSMakeRange(i-1, 1);
if ([[self.calcString substringWithRange:prevChar] isEqualToString:#"0"]||
[[self.calcString substringWithRange:prevChar] isEqualToString:#"."])
length--;
else
break;
}
self.calcString = [self.calcString substringToIndex:length];
}
}
This works
display.text = [#(trig) stringValue];
it is because of your datatype cannot be formatted is such a manner.
Is there a way in Objective-C on iOS to spell out an integer number as text?
For example, if I have
NSInteger someNumber = 11242043;
I would like to know some function so that would return a string similar to "eleven million two hundred forty two thousand forty three."
Apple has a lot of handy formatting functionality built in for many data types. Called a "formatter," they can convert objects to/from string representations.
For your case, you will be using NSNumberFormatter, but if you have an integer you need to convert it to an NSNumber first. See below example.
NSInteger anInt = 11242043;
NSString *wordNumber;
//convert to words
NSNumber *numberValue = [NSNumber numberWithInt:anInt]; //needs to be NSNumber!
NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc] init];
[numberFormatter setNumberStyle:NSNumberFormatterSpellOutStyle];
wordNumber = [numberFormatter stringFromNumber:numberValue];
NSLog(#"Answer: %#", wordNumber);
// Answer: eleven million two hundred forty-two thousand forty-three
If you'd like to learn more about formatters:
https://developer.apple.com/library/content/documentation/General/Conceptual/Devpedia-CocoaApp/Formatter.html
Power of extension for Swift 5
import Foundation
public extension Int {
var asWord: String? {
let numberValue = NSNumber(value: self)
let formatter = NumberFormatter()
formatter.numberStyle = .spellOut
return formatter.string(from: numberValue)
}
}
var value = 2
if let valueAsWord = value.asWord {
//do something with your worded number here
print("value worded = \(valueAsWord)")
} else {
print("could not word value :(")
}
Note: Edited to protect against formatter.string(from: returning nil which is highly not likely, but still possible.
Output:
value worded = two
From the docs:
NSNumberFormatterSpellOutStyle
Specifies a spell-out format; for example, “23” becomes “twenty-three”.
Available in iOS 2.0 and later.
Declared in NSNumberFormatter.h.
As your question isn't very specific, I won't post full-fledged code source either.
With Swift 5 / iOS 12.2, NumberFormatter has a numberStyle property that can be set with value NumberFormatter.Style.spellOut. spellOut has the following declaration:
case spellOut = 5
A style format in which numbers are spelled out in the language defined by the number formatter locale.
For example, in the en_US locale, the number 1234.5678 is represented as one thousand two hundred thirty-four point five six seven eight; in the fr_FR locale, the number 1234.5678 is represented as mille deux cent trente-quatre virgule cinq six sept huit.
This style is supported for most user locales. If this style doesn't support the number formatter locale, the en_US locale is used as a fallback.
The Playground code below shows how to convert an integer to a spell-out text using NumberFormatter spellOut style:
import Foundation
let integer = 2018
let formatter = NumberFormatter()
formatter.numberStyle = NumberFormatter.Style.spellOut
let spellOutText = formatter.string(for: integer)!
print(spellOutText) // prints: two thousand eighteen
We can do this in swift like this.
let formatter = NSNumberFormatter()
formatter.numberStyle = NSNumberFormatterStyle. SpellOutStyle
println("\(identifier) \(formatter.stringFromNumber(1234.5678))")
You can use the below function to convert an integer to words using swift native number style.
func toWords<N>(number: N) -> String? {
let formatter = NumberFormatter()
formatter.numberStyle = .spellOut
switch number {
case is Int, is UInt, is Float, is Double:
return formatter.string(from: number as! NSNumber)
case is String:
if let number = Double(number as! String) {
return formatter.string(from: NSNumber(floatLiteral: number))
}
default:
break
}
return nil
}
print(toWords(number: 12312))
print(toWords(number: "12312"))
For my own reference, this is #moca's answer, but ready for use:
- (NSString *) spellInt:(int)number {
NSNumber *numberAsNumber = [NSNumber numberWithInt:number];
NSNumberFormatter *formatter = [NSNumberFormatter new];
[formatter setNumberStyle:NSNumberFormatterSpellOutStyle];
return [formatter stringFromNumber:numberAsNumber];
}
Note: This is using ARC.
I have a string called realEstateWorth with a value of $12,000,000.
I need this same string to remain a string but for any number (such as the one above) to be displayed as $12 MILLION or $6 MILLION. The point is it needs the words "MILLION" to come after the number.
I know there is nsNumberFormatter that can convert strings into numbers and vice versa but can it do what I need?
If anyone has any ideas or suggestions, it would be much appreciated.
Thank you!
So as I see it, you have two problems:
You have a string representation of something that's actually a number
You (potentially) have a number that you want formatted as a string
So, problem #1:
To convert a string into a number, you use an NSNumberFormatter. You've got a pretty simple case:
NSNumberFormatter *f = [[NSNumberFormatter alloc] init];
[f setNumberStyle:NSNumberFormatterCurrencyStyle];
NSNumber *n = [f numberFromString:#"$12,000,000"];
// n is 12000000
That was easy! Now problem #2:
This is trickier, because you want a mixed spell-out style. You could consider using an NSNumberFormatter again, but it's not quite right:
[f setNumberStyle:NSNumberFormatterSpellOutStyle];
NSString *s = [f stringFromNumber:n];
// s is "twelve million"
So, we're closer. At this point, you could perhaps maybe do something like:
NSInteger numberOfMillions = [n integerValue] / 1000000;
if (numberOfMillions > 0) {
NSNumber *millions = [NSNumber numberWithInteger:numberOfMillions];
NSString *numberOfMillionsString = [f stringFromNumber:millions]; // "twelve"
[f setNumberStyle:NSNumberFormatterCurrencyStyle];
NSString *formattedMillions = [f stringFromNumber:millions]; // "$12.00"
if ([s hasPrefix:numberOfMillionsString]) {
// replace "twelve" with "$12.00"
s = [s stringByReplacingCharactersInRange:NSMakeRange(0, [numberOfMillionsString length]) withString:formattedMillions];
// if this all works, s should be "$12.00 million"
// you can use the -setMaximumFractionDigits: method on NSNumberFormatter to fiddle with the ".00" bit
}
}
However
I don't know how well this would work in anything other than english. CAVEAT IMPLEMENTOR
Worst case scenario, you could implement a category on NSString to implement the behaviour you want.
In the method that you would do in that category you could take an NSNumberFormatter to bring that string to a number and by doing some modulo operation you could define if you need the word Million, or Billion, etc. and put back a string with the modulo for Million or other way you need it to be.
That way you could just call that method on your NSString like this :
NSString *humanReadable = [realEstateWorth myCustomMethodFromMyCategory];
And also.
NSString are immutable, so you can't change it unless you assign a new one to your variable.
I'd recommend storing this value as an NSNumber or a float. Then you could have a method to generate an NSString to display it like:
- (NSString*)numberToCurrencyString:(float)num
{
NSString *postfix = #"";
if (num > 1000000000)
{
num = num / 1000000000;
postfix = #" Billion";
}
else if (num > 1000000)
{
num = num / 1000000;
postfix = #" Million";
}
NSString *currencyString = [NSString stringWithFormat:#"%.0f%#", num, postfix];
return currencyString;
}
Note: Your question states that your input needs to remain a string. That's fine. So you'd need to 1.) first parse the number out of the string and 2.) then reconvert it to a string from a number. I've shown how to do step 2 of this process.
I'm trying to do some number rounding and conversion to a string to enhance the output in an Objective-C program.
I have a float value that I'd like to round to the nearest .5 and then use it to set the text on a label.
For example:
1.4 would be a string of: 1.5
1.2 would be a string of: 1
0.2 would be a string of: 0
I've spent a while looking on Google for an answer but, being a noob with Objective-C, I'm not sure what to search for! So, I'd really appreciate a pointer in the right direction!
Thanks,
Ash
Thanks for the pointers everyone, I've managed to come up with a solution:
float roundedValue = round(2.0f * number) / 2.0f;
NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
[formatter setMaximumFractionDigits:1];
[formatter setRoundingMode: NSNumberFormatterRoundDown];
NSString *numberString = [formatter stringFromNumber:[NSNumber numberWithFloat:roundedValue]];
[formatter release];
The above works for the test cases I threw at it, but if anyone knows a better way to do this I'd be interested to hear it!
float floatVal = 1.23456;
Rounding
int roundedVal = lroundf(floatVal);
NSLog(#"%d",roundedVal);
Rounding Up
int roundedUpVal = ceil(floatVal);
NSLog(#"%d",roundedUpVal);
Rounding Down
int roundedDownVal = floor(floatVal);
NSLog(#"%d",roundedDownVal);
NSString *numberString = [NSString stringWithFormat:#"%f", round(2.0f * number) / 2.0f];
Use lroundf() to round a float to integer and then convert the integer to a string.
NSString *numberString = [NSString stringWithFormat:#"%d",lroundf(number)];
I'd recommend looking into using NSNumberFormatter.
a simple way:
float theFloat = 1.23456;
int rounded = roundf(theFloat); NSLog(#"%d",rounded);
int roundedUp = ceil(theFloat); NSLog(#"%d",roundedUp);
int roundedDown = floor(theFloat); NSLog(#"%d",roundedDown);
// Note: int can be replaced by float
NSString *intNumberString = [NSString stringWithFormat:#"%d", (int)floatNumber];
Following Technique worked for me in a financial application.
NSString *dd=[NSString stringWithFormat:#"%0.2f",monthlyPaymentCalculated];
monthlyPaymentCalculated=[dd doubleValue];
self.monthlyPaymentCritical=monthlyPaymentCalculated;
what is did is first is rounded it with %0.2f and stored it in NSString then i simply converted it again into double and result was good for my calculation.
With these functions you can round to any value.. If you use p=2, you get even numbers.
float RoundTo(float x, float p)
{
float y = 1/p;
return int((x+(1/(y+y)))*y)/y;
}
float RoundUp(float x, float p)
{
float y = 1/p;
return int((x+(1/y))*y)/y;
}
float RoundDown(float x, float p)
{
float y = 1/p;
return int(x*y)/y;
}
I needed to be able to round to a specific digit (not necessarily to whole integers). I made a NSNumber category (based off Ash's answer) and added the following method to it:
- (NSString *)stringByRounding:(NSNumberFormatterRoundingMode)roundingMode
toPositionRightOfDecimal:(NSUInteger)position
{
NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
[formatter setMaximumFractionDigits:position];
[formatter setRoundingMode:roundingMode];
NSString *numberString = [formatter stringFromNumber:self];
return numberString;
}
Which allows me to use it like so:
[aNumber stringByRounding:NSNumberFormatterRoundUp toPositionRightOfDecimal:2];
I can use it to round to integers by passing in 0 as the second parameter:
[aNumber stringByRounding:NSNumberFormatterRoundPlain toPositionRightOfDecimal:0];