NSNumberFormatter Scientific Form Output - objective-c

I have NSNumber and NSResultFormatter, that converts number into string and displays it on screen.
In scientific form output for large numbers is "1.345e10" and for small numbers is "1.345e-10".
I want to output large numbers as "1.345e+10", like in standart iOS calc app. How can I to do it?

You can achieve that by setting a custom number format, for example:
NSNumberFormatter *fmt = [[NSNumberFormatter alloc] init];
[fmt setExponentSymbol:#"e"];
[fmt setPositiveFormat:#"0.###E+0"];
NSString *s = [fmt stringFromNumber:#(12345678900)];
// 1.235e+10
Custom number formats are documented in http://www.unicode.org/reports/tr35/tr35-25.html#Number_Format_Patterns.

Related

How to round a float to 2 decimal places?

This is my algorithm to find out the speed of my game.
self.speed=.7-self.score/50;
Now how can I make self.speed round to 2 decimal places?
Note: my answer assumes you only care about the number of decimals for the purpose of displaying the value to the user.
When you setup your NSNumberFormatter to format the number into a string for display, setup the formatter with a maximum of two decimal places.
NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
[formatter setNumberStyle:NSNumberFormatterDecimalStyle];
[formatter setMaximumFractionDigits:2];
NSString *formattedNumber = [formatter stringFromNumber:#(self.speed)];
You have the option of using the setRoundingMode: method if you need a specific round method.
BTW - you shouldn't use a string format for this because it doesn't take the user's locale into account to format the number properly.
floats are handled in IEEE754 format, you can't directly decide how many decimal places will be used.You can directly decide how many bits will be used, or indirectly round the las part of the number doing this:
NSString* str=[NSString stringWithFormat: #"%.2f", number];
number= atof([str UTF8String]);
But like maddy pointed, you only need to round/truncate the unwanted decimal digits only when presenting the number to the user, so you could only use the %.2f format specifier when printing it, or use a formatter.
self.speed = (int)(self.speed * 100 + 0.5) / 100.0;
if you want to have that as a string:
NSString *speedString = [NSString stringWithFormat: #"%.2f", self.speed];

NSNumberFormatter customize?

I wish to use NSNumberFormatter to merely attached a percent ('%') to the supplied number WITHOUT having it multiplied by 100.
The canned kCFNumberFormatterPercentStyle automatically x100 which I don't want.
For example, converting 5.0 to 5.0% versus 500%.
Using the following:
NSNumberFormatter *percentFormatter = [[NSNumberFormatter alloc] init];
[percentFormatter setNumberFormat:#"##0.00%;-##0.00%"];
But 'setNumberFormat' doesn't exist in NSNumberFomatter.
I need to use this NSNumberFormatter for my Core-Plot label.
How can I customize NSNumberFormat?
Ric.
Source: Apple's NSDecimalNumber reference.
Apparently I hinted the answer by saying that I didn't want the output to be 100x.
I'm working with a NSDecimalNumber which has the 'setMultiplier' method.
So, after I used the canned kCFNumberFormatterPercentStyle for the formatter, I used 'setMultiplier:1' as follows:
NSNumberFormatter *percentFormatter = [[NSNumberFormatter alloc] init];
[percentFormatter setNumberStyle:kCFNumberFormatterPercentStyle];
[percentFormatter setMultiplier:[NSNumber numberWithInt:1]];
Have you tried using setMultiplier to prevent it from multiplying by 100?
NSNumberFormatter *percentFormatter = [[NSNumberFormatter alloc] init];
[percentFormatter setNumberStyle: NSNumberFormatterPercentStyle];
[percentFormatter setMultiplier:1];
If adding the percent sign is all you need to accomplish, an alternative using NSNumberFormatterwould be:
[NSString stringWithFormat:#"%3.2f%%", [myNumber doubleValue]];
And you should adjust the precision specifier (3.2) to suit the number of digits you want to display.

NSString to NSNumber with some decimal separator

The app I'm building now has a possibility to "download" text files and get the numbers from there. In the simulator everything works perfectly, but when I tested it on a device it just crashed. After a while I figured out that the problem was with the decimal separators. In that file I used . and the local setting of my iPhone require ,. Example of that string:
Product 1;100.00
Product 2;82.85
Product 3;95.12
//etc...
After changing the the first few . into , I could successfully run the app till it reached the first ., so that's the problem.
I can easily replace all . into , programmatically, BUT I want this app to work in any country with any number format and not limit it to some specific market.
The code I was using to get these numbers:
NSString *fileContents = [[NSUserDefaults standardUserDefaults]objectForKey:theKey];
NSArray *allLinedStrings = [fileContents componentsSeparatedByCharactersInSet:[NSCharacterSet newlineCharacterSet]];
NSMutableArray *allStringNormalized = [NSMutableArray array];
NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
[formatter setNumberStyle:NSNumberFormatterDecimalStyle];
for (int i = 0; i < allLinedStrings.count; i++) {
NSString *bla = [allLinedStrings objectAtIndex:i];
NSArray *bla1 = [bla componentsSeparatedByString:#";"];
[allStringNormalized addObject:[formatter numberFromString:[bla1 objectAtIndex:1]]];
}
self.values = [NSArray arrayWithArray:allStringNormalized];
Any help would be appreciated.
Thank you :)
If I understand the problem correctly, you want NSNumberFormatter to always use . as the decimal separator, regardless of the phone's locale. The solution to this is simple: use the instance methods setDecimalSeparator: and setCurrencyDecimalSeparator: of NSNumberFormatter to set the decimal separator to ..
Note that you don't need to set both decimal separators. You use setDecimalSeparator: if your numberStyle is NSNumberFormatterDecimalStyle and setCurrencyDecimalSeparator: if your numberStyle is NSNumberFormatterCurrencyStyle.
See the documentation for more details.

NSNumberFormatter: string to Double

I am trying to take a user input from a text field and format it into a double value for core data. Currently my code looks like:
NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc] init];
[numberFormatter setNumberStyle:NSNumberFormatterDecimalStyle];
NSNumber *weightDouble = [numberFormatter numberFromString:#"weight.text"];
However, if I print weightDouble I get 0, if I print out the text from the UI input I get the correct number. Any ideas on what I am doing wrong here? I get no errors on the build and it operates and saves fine (other than saving 0 no matter the input)
First of all:
(If 'weight' is a UITextField)
NSNumber *weightDouble = [numberFormatter numberFromString:weight.text];
With numberFromString:#"weight.text" you will be getting the value of the text 'weight.text' which is in fact 0.
But why not just double weightDouble = weight.text.doubleValue? (Except maybe localization concerns)

How to format this NSString correctly?

I want to format a string that can look like that:
0.0580 which means 5.8 ct
0.1580 which means 15.8 ct
1.1580 which means 1.15 €
So the string can be anything in x.xxxx format. Now I started formating it but I am new to objective-c and iOS.
First I want to remove the last character because the last number does not really matter and I don't want to round numbers.
NSString *responseString = [responseData
substringWithRange:NSMakeRange(1,
[responseData length]-2)];
This gives me x.xxx so far. Any idea how to proceed and what code to use? Are there any libraries on that?
Take a look at the NSNumberFormatter class. It should do what you need. Something like this:
NSNumberFormatter *numFormatter = [[NSNumberFormatter alloc] init];
NSNumber *myNumber = [NSNumber numberWithDouble:[#"0.158" doubleValue]];
[numFormatter setNumberStyle:NSNumberFormatterCurrencyStyle];
NSString *formattedValue = [numFormatter stringFromNumber:myNumber];
[numFormatter release];
Also look at NSNumberFormatterStyle and NSNumberFormatterBehavior to control the format.
Once you have your number in the form x.xxx, you could do something like:
float floatValue = [#"0.158" floatValue]; // Get your string as a number.
floatValue *= 100; // Turn '0.158' into '1.58'
Does this answer your question? I'm not quite sure that it does, so update your question and I will try to assist you better.