How do I round a NSNumber to zero decimal spaces - objective-c

How do I round an NSNumber to zero decimal spaces, in the following line it seems to keep the decimal spaces:
NSNumber holidayNightCount = [NSNumber numberWithDouble:sHolidayDuration.value];

Typically casting to int truncates. For example, 3.4 becomes 3 (as is desired), but 3.9 becomes 3 also. If this happens, add 0.5 before casting
int myInt = (int)(sHolidayDuration.value + 0.5);

Here's a bit of a long winded approach
float test = 1.9;
NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
[formatter setRoundingMode:NSNumberFormatterRoundHalfUp];
[formatter setMaximumFractionDigits:0];
NSLog(#"%#",[formatter stringFromNumber:[NSNumber numberWithFloat:test]]);
[formatter release];

If you only need an integer why not just use an int
int holidayNightCount = (int)sHolidayDuration.value;
By definition an int has no decimal places
If you need to use NSNumber, you could just cast the Double to Int and then use the int to create your NSNumber.
int myInt = (int)sHolidayDuration.value;
NSNumber holidayNightCount = [NSNumber numberWithInt:myInt];

you can also do the following: int roundedRating = (int)round(rating.floatValue);

Floor the number using the old C function floor() and then you can create an NSInteger which is more appropriate, see:
https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man3/floor.3.html ....
NSInteger holidayNightCount = [NSNumber numberWithInteger:floor(sHolidayDuration.value)].integerValue;
Further information on the topic here: http://eureka.ykyuen.info/2010/07/19/objective-c-rounding-float-numbers/
Or you could use NSDecimalNumber features for rounding numbers.

Related

What's the intended way to turn a NSString into a NSDecimalNumber with two decimal places?

I'm currently using the following methodology to turn a NSString number (like #"123.456") into a NSDecimalNumber after rounding (like 123.46), but it feels hacky. Is there a more intended solution?
+ (NSDecimalNumber*)decimalNumberForString:(NSString*)str accuracy:(NSUInteger)accuracy
{
NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
formatter.numberStyle = NSNumberFormatterNoStyle;
formatter.maximumFractionDigits = accuracy;
formatter.roundingMode = NSNumberFormatterRoundHalfUp;
NSNumber *numberVersion = [formatter numberFromString:str];
return [[NSDecimalNumber alloc] initWithDecimal:numberVersion.decimalValue];
}
Take a look at NSDecimalNumberHandler and NSDecimalNumber's
-decimalNumberByRoundingAccordingToBehavior:
method.
You can create a NSDecimalNumber with your unedited string, then create a new NSDecimal number that's rounded according to the rules you set on NSDecimalNumberHandler.
There's no need to edit your input string.
Use [NSDecimalNumber decimalNumberWithString:], like this:
NSDecimalNumber *number = [NSDecimalNumber decimalNumberWithString:#"123.456"];
The number of decimal places only affects the string representation of the number; once the number is stored in an NSDecimalNumber object it can be formatted back to a string in any way you desire.

Rounded of a float with a decimal

Do someone know if there is a method in order to round a float two numbers after the comme.
Examples :
10.28000 -> 10.3
13.97000 -> 14.0
5.41000 -> 5.4
Thanks a lot !
Regards,
Sébastien ;)
Use NSNumberFormatter to create a string with the specified faction digits.
float num = 10.28000;
formatter = [[NSNumberFormatter alloc] init];
[formatter setMaximumFractionDigits:1];
NSNumber *value = [NSNumber numberWithFloat:num];
NSString *newNumString = [formatter stringFromNumber:value];
Try this:
float aFloatValue = 3.1415926;
NSString *formatted = [NSString stringWithFormat:#"%01.1f", aFloatValue];
NSLog(#"Formatted: %#", formatted);
Think of it as a good old sprintf.
you could also try
float num = 10.28000
float result = (roundf(num * 10.0))/10.0;
(multiply by 10, then round, then divide by 10 again)
don't forget the .0 so that the division is by a float and not by an integer, which will round it again
The pure Cocoa way with NSRoundPlain behaviour:
- (NSDecimalNumber *)decimalNumberForFloat:(float)f_
{
NSNumber *number = [NSNumber numberWithFloat:f_];
NSDecimal decimal = [number decimalValue];
NSDecimalNumber *originalDecimalNumber = [NSDecimalNumber decimalNumberWithDecimal:decimal];
NSDecimalNumberHandler *roundingBehavior = [NSDecimalNumberHandler decimalNumberHandlerWithRoundingMode:NSRoundPlain
scale:0
raiseOnExactness:NO
raiseOnOverflow:NO
raiseOnUnderflow:NO
raiseOnDivideByZero:NO];
return [originalDecimalNumber decimalNumberByRoundingAccordingToBehavior:roundingBehavior];
}
since NSDecimalNumber is a subclass of NSNumber, to obtain the primitive float call -[NSDecimalNumber floatValue]
Try this out:
float myFloat = 10.4246f;
myFloat = ((int) ((myFloat * 100) + 5)) / 100.0f;
float fval = 1.54f;
float nfval = ceilf(fval * 10.0f + 0.5f)/10.0f;

objective c - Xcode long int display with formatting

I’m having issues with this when the numbers are large. For example if the number is 3670000000, I want the label to be 3,670,000,000. When the numbers are large it gives me a value of 2,147,483,657. I’m sure it must be a variable length issue. I tried using long long int for numC. Any suggestions would be greatly appreciated. Thanks.
int numC;
NSNumberFormatter *formatter = [NSNumberFormatter new];
[formatter setNumberStyle:NSNumberFormatterDecimalStyle];
NSString *valuestring= [NSString stringWithFormat:#"%#", [[values objectAtIndex:indexA] objectForKey:#"hits"]];
numC=[valuestring intValue];
NSString *results = [formatter stringFromNumber:[NSNumber numberWithInteger:numC]];
label1.text =results;
The int type cannot hold a value greater than 2,147,483,657. You could use an unsigned int and the maximum value would be 4,294,967,295. Look here for more information. You could try this too to extend the range of the data type:
long long int numC;
//Number formatter and string operations
numC = [valuestring longLongValue];
NSString *results = [formatter stringFromNumber:[NSNumber numberWithLongLong: numC]];
label1.text = results;
Additionally, if none of the values you are retrieving contain a negative value, you could make it an unsigned long long int. In that case, make your code this:
unsigned long long int numC;
//Number formatter and string operations
numC = [valuestring longLongValue];
NSString *results = [formatter stringFromNumber:[NSNumber numberWithUnsignedLongLong: numC]];
label1.text = results;
Also make sure that in this line...
NSString *valuestring= [NSString stringWithFormat:#"%#", [[values objectAtIndex:indexA] objectForKey:#"hits"]];
...the value you are retrieving is a long long int.
Hope this helps!
There is also the C++ class for bigInteger if you really need to do operations with numbers larger than allowed by int. If you don't need to do many operations, store the number as a NSString. Then to work with it just take the end of the string, convert it to an int, do your operations, then put the number back into the string.

Why aren't the decimals printed to the string?

In order to get a string with 2 decimals value I've tried:
[[NSString stringWithFormat:#"%.2f",[[self CurrentValue] doubleValue]]]
this
[self CurrentValue] stringValue]
and this:
NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
formatter.numberStyle = NSNumberFormatterCurrencyStyle;
NSString *string = [formatter stringFromNumber:[self CurrentValue]];
[formatter release];
But it doesn't work. THe original number is a float = 22, and I always get a string "22", and not "22.00".
Thanks
I ran a few test scenarios and hopefully this can help you get to the bottom of it. The formatter is ideal if you are doing a currency, otherwise string1 is ideal. To work from this example you can set number up - NSNumber * number = [self CurrentValue];
NSNumber * number = [NSNumber numberWithInt:22];
NSString * string1 = [NSString stringWithFormat:#"%.2f",[number doubleValue]];
NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
formatter.numberStyle = NSNumberFormatterCurrencyStyle;
NSString *string2 = [formatter stringFromNumber:number];
[formatter release];
NSLog(#"string 1 %#\nstring 2 %#\nstring 3 %#", string1, string2, [number stringValue]);
//output
string 1 22.00
string 2 $22.00
string 3 22
// top code with NSNumber * number = [NSNumber numberWithFloat:22];
string 1 22.00
string 2 $22.00
string 3 22
// top code with NSNumber * number = [NSNumber numberWithFloat:22.0];
string 1 22.00
string 2 $22.00
string 3 22
Summary:
The way the number is created is not significant here to the output if it is truly an int (floats with such as 4.20 will work as expected in every case, but every int value 22,22.0,22.000 gets treated the same by all 3 ways of creating a number. So choose the format you like best and implement that.
Seems you have extra [] around. You can try
[NSString stringWithFormat:#"%.2f",[[self CurrentValue] floatValue]]
or
[NSString stringWithFormat:#"%.2lf",[[self CurrentValue] doubleValue]] both are good to go.
It actually much simpler.
You said that "The original number is a float = 22". Now, remember that obj-c runtime class may differ from declared one. And when you instantiate your float variable with actually integer value - it is an integer one at runtime! You should change it to one of the following:float someFloatValue = 22f;float someFloatValue = 22.0;float someFloatValue = (float)22; (not sure about that one thought)
Happy coding...

How to convert an NSString into an NSNumber

How can I convert a NSString containing a number of any primitive data type (e.g. int, float, char, unsigned int, etc.)? The problem is, I don't know which number type the string will contain at runtime.
I have an idea how to do it, but I'm not sure if this works with any type, also unsigned and floating point values:
long long scannedNumber;
NSScanner *scanner = [NSScanner scannerWithString:aString];
[scanner scanLongLong:&scannedNumber];
NSNumber *number = [NSNumber numberWithLongLong: scannedNumber];
Thanks for the help.
Use an NSNumberFormatter:
NSNumberFormatter *f = [[NSNumberFormatter alloc] init];
f.numberStyle = NSNumberFormatterDecimalStyle;
NSNumber *myNumber = [f numberFromString:#"42"];
If the string is not a valid number, then myNumber will be nil. If it is a valid number, then you now have all of the NSNumber goodness to figure out what kind of number it actually is.
You can use -[NSString integerValue], -[NSString floatValue], etc. However, the correct (locale-sensitive, etc.) way to do this is to use -[NSNumberFormatter numberFromString:] which will give you an NSNumber converted from the appropriate locale and given the settings of the NSNumberFormatter (including whether it will allow floating point values).
Objective-C
(Note: this method doesn't play nice with difference locales, but is slightly faster than a NSNumberFormatter)
NSNumber *num1 = #([#"42" intValue]);
NSNumber *num2 = #([#"42.42" floatValue]);
Swift
Simple but dirty way
// Swift 1.2
if let intValue = "42".toInt() {
let number1 = NSNumber(integer:intValue)
}
// Swift 2.0
let number2 = Int("42')
// Swift 3.0
NSDecimalNumber(string: "42.42")
// Using NSNumber
let number3 = NSNumber(float:("42.42" as NSString).floatValue)
The extension-way
This is better, really, because it'll play nicely with locales and decimals.
extension String {
var numberValue:NSNumber? {
let formatter = NumberFormatter()
formatter.numberStyle = .decimal
return formatter.number(from: self)
}
}
Now you can simply do:
let someFloat = "42.42".numberValue
let someInt = "42".numberValue
For strings starting with integers, e.g., #"123", #"456 ft", #"7.89", etc., use -[NSString integerValue].
So, #([#"12.8 lbs" integerValue]) is like doing [NSNumber numberWithInteger:12].
You can also do this:
NSNumber *number = #([dictionary[#"id"] intValue]]);
Have fun!
If you know that you receive integers, you could use:
NSString* val = #"12";
[NSNumber numberWithInt:[val intValue]];
Here's a working sample of NSNumberFormatter reading localized number NSString (xCode 3.2.4, osX 10.6), to save others the hours I've just spent messing around. Beware: while it can handle trailing blanks ("8,765.4 " works), this cannot handle leading white space and this cannot handle stray text characters. (Bad input strings: " 8" and "8q" and "8 q".)
NSString *tempStr = #"8,765.4";
// localization allows other thousands separators, also.
NSNumberFormatter * myNumFormatter = [[NSNumberFormatter alloc] init];
[myNumFormatter setLocale:[NSLocale currentLocale]]; // happen by default?
[myNumFormatter setFormatterBehavior:NSNumberFormatterBehavior10_4];
// next line is very important!
[myNumFormatter setNumberStyle:NSNumberFormatterDecimalStyle]; // crucial
NSNumber *tempNum = [myNumFormatter numberFromString:tempStr];
NSLog(#"string '%#' gives NSNumber '%#' with intValue '%i'",
tempStr, tempNum, [tempNum intValue]);
[myNumFormatter release]; // good citizen
I wanted to convert a string to a double. This above answer didn't quite work for me. But this did: How to do string conversions in Objective-C?
All I pretty much did was:
double myDouble = [myString doubleValue];
Thanks All! I am combined feedback and finally manage to convert from text input ( string ) to Integer. Plus it could tell me whether the input is integer :)
NSNumberFormatter * f = [[NSNumberFormatter alloc] init];
[f setNumberStyle:NSNumberFormatterDecimalStyle];
NSNumber * myNumber = [f numberFromString:thresholdInput.text];
int minThreshold = [myNumber intValue];
NSLog(#"Setting for minThreshold %i", minThreshold);
if ((int)minThreshold < 1 )
{
NSLog(#"Not a number");
}
else
{
NSLog(#"Setting for integer minThreshold %i", minThreshold);
}
[f release];
I think NSDecimalNumber will do it:
Example:
NSNumber *theNumber = [NSDecimalNumber decimalNumberWithString:[stringVariable text]]];
NSDecimalNumber is a subclass of NSNumber, so implicit casting allowed.
What about C's standard atoi?
int num = atoi([scannedNumber cStringUsingEncoding:NSUTF8StringEncoding]);
Do you think there are any caveats?
You can just use [string intValue] or [string floatValue] or [string doubleValue] etc
You can also use NSNumberFormatter class:
you can also do like this code 8.3.3 ios 10.3 support
[NSNumber numberWithInt:[#"put your string here" intValue]]
NSDecimalNumber *myNumber = [NSDecimalNumber decimalNumberWithString:#"123.45"];
NSLog(#"My Number : %#",myNumber);
Try this
NSNumber *yourNumber = [NSNumber numberWithLongLong:[yourString longLongValue]];
Note - I have used longLongValue as per my requirement. You can also use integerValue, longValue, or any other format depending upon your requirement.
Worked in Swift 3
NSDecimalNumber(string: "Your string")
I know this is very late but below code is working for me.
Try this code
NSNumber *number = #([dictionary[#"keyValue"] intValue]]);
This may help you. Thanks
extension String {
var numberValue:NSNumber? {
let formatter = NumberFormatter()
formatter.numberStyle = .decimal
return formatter.number(from: self)
}
}
let someFloat = "12.34".numberValue