Objective-C: Separate number right/left of decimal - objective-c

I am trying to separate the left and right numbers from a float so I can turn each into a string. So for example, 5.11, I need to be able to turn 5 into a string, and 11 into another string.
// from float: 5.11
NSString * leftNumber = #"5";
NSString * rightNumber = #"11";
From this, I can turn 5.11 into 5' 11".

One way:
Use stringWithFormat to convert to string "5.11".
Use componentsSeparatedByString to seperate into an array of "5" and "11".
Combine with stringWithFormat.

You could use NSString stringWithFormat and math functions for that:
float n = 5.11;
NSString * leftNumber = [NSString stringWithFormat:#"%0.0f", truncf(n)];
NSString * rightNumber = [[NSString stringWithFormat:#"%0.2f", fmodf(n, 1.0)] substringFromIndex:2];
NSLog(#"'%#' '%#'", leftNumber, rightNumber);
However, this is not ideal, especially for representing lengths in customary units, because 0.11 ft is not 11 inches. You would be better off representing the length as an integer in the smallest units that you support (say, for example, 1/16-th of an inch) and then convert it to the actual length for display purposes. In this representation 5 ft 11 in would be 5*12*16 + 11*16 = 1136.

You could use a number formatter as such
NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
formatter.numberStyle = NSNumberFormatterDecimalStyle;
formatter.decimalSeparator = #"'";
formatter.positiveSuffix = #"\"";
formatter.alwaysShowsDecimalSeparator = true;
NSString *numberString = [formatter stringFromNumber:#(5.11)];
// Output : 5'11"

Related

NSNumberFormatter for converting to currencies

I need to create a NSFormatter that takes integer values, and sends them to formatted currencies, but the catch is it must add K, and M for thousands and millions. E.G:
130000 -> $130k
12000 -> $12k
10000000 ->$10M
It has to be a datatype NSNumberFormatter since I'll be using it to set a property which takes parameter NSNumberFormatter (I'm formatting the axis labels of a graph).
NSByteCountFormatter can help:
int number = 100000;
NSString *binaryFormatted = [NSByteCountFormatter stringFromByteCount:number countStyle:NSByteCountFormatterCountStyleDecimal];
NSLog(#"binaryFormatted: %#", binaryFormatted);
NSString *digits = [binaryFormatted substringToIndex:binaryFormatted.length-3];
NSString *units = [binaryFormatted substringWithRange:NSMakeRange(binaryFormatted.length-2, 1)];
NSString *currencyFormatted = [NSString stringWithFormat:#"$%#%#", digits, units];
NSLog(#"currencyFormatted: %#", currencyFormatted);
NSLog output
binaryFormatted: 100 KB
currencyFormatted: $100K

Convert back localized NSString number (> 4 digits) to integer

I used the localizedStringWithFormat: method on NSString class to convert a seven digit integer number to an NSString somewhere in my code and need to convert it back to an integer now.
As my App is localized for different regions with different separators after three digits (e.g. '.' in the U.S. and ',' in Germany), what's the best way to convert a localized NSString integer value to an integer?
I tried integerValue on my string as follows but it didn't work:
// Somewhere in code:
int num = 1049000;
NSString *myLocalizedNumString = [NSString localizedStringWithFormat:#"%d", num];
// myLocalizedNumString (U.S.): '1,049,000'
// myLocalizedNumString (Germany): '1.049.000'
// Somewhere else where I have a reference to my string but none to the num:
int restoredNum = [myLocalizedNumString integerValue];
// restoredNum isn't 1049000 (it's 0, the initial value)
What would be a good working way of doing it?
Despite its name NSNumberFormatter converts both ways, it is also a string parser. Using the method numberFromString after setting the number formatter’s numberStyle property to NSNumberFormatterDecimalStyle solves your problem.
The code might look as follows:
NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
formatter.numberStyle = NSNumberFormatterDecimalStyle;
NSInteger restoredNum = [[formatter numberFromString:myLocalizedNumString] integerValue];

Adding integers which are in strings in objective-c

For example I have "$100" and "$50" in two strings, I want to add them to get an output "$150".
I know the general method(converting them into integers and adding them), but i am searching for a shorter method which does not call many functions
You can use an NSNumberFormatter to parse the string into a NSNumber, Sum them and then convert back to String :
NSString *strNum1 = "$100";
NSString *strNum2 = "$150";
NSNumberFormatter * f = [[NSNumberFormatter alloc] init];
[f setNumberStyle:NSNumberFormatterCurrencyStyle];
NSNumber * myFirstNumber = [f numberFromString:strNum1];
NSNumber * mySecNumber = [f numberFromString:strNum2];
NSNumber *sum = [NSNumber numberWithFloat:([myFirstNumber floatValue] + [mySecNumber floatValue])];
NSString * strSum = [f stringFromNumber:sum];
float result = [[fiftyBucks substringFromIndex:1] floatValue] + [[hundredBucks substringFromIndex:1] floatValue];
or use NSScanner, but it will be little longer, but more reliably/safely:
float fifty, hundred, result;
[[NSScaner scannerWithString: fiftyBucks] scanFloat: &fifty];
[[NSScaner scannerWithString: hundredBucks] scanFloat: &hundred];
result = fifty + hundred;
I think you better store the price at CGfloat instead.
showing a string "$100" is a front-end task and calculating the sum of the prices are back end task. These two should be seperated.
If you store the price as a CGFloat, you can simply do the maths.
And when you wanna show that string, juz implement a method.
- (NSString *)priceLabel:(CGFloat) _price {
return [NSString stringWithFormat: #"$.1f", _price];
}
Besides, don't be afraid of making a Front-end Helper model when you code. I put all this kind of minor method in this model as a class method. Wherever you need reuse this method, you can simply import the model.

Rounding numbers in Objective-C

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];

Make a float only show two decimal places

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]];