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
This question already has answers here:
How to convert an NSString into an NSNumber
(18 answers)
Closed 8 years ago.
I've tried to convert the UITextfield Value Into a float first then convert it to an NSNumber but that doesn't seem to work as seen below.
float carb = [self.carbGrams.text floatValue];
NSLog(#"%.2f", carb);
nCarbGrams = carb;
In the last line I get this error message:
Assigning to 'NSNumber *__strong' from incompatible type 'float'
I've then just tried assigning carb as an NSNumber by doing this
NSNumber *carb = [self.carbGrams.text floatValue];
NSLog(#"%.2f", carb);
nCarbGrams = carb;
But I get this error message instead :
Initializing 'NSNumber *__strong' with an expression of incompatible type 'float'
As I've read I though NSNumber could accept any type of numeric value but I seem to be incorrect, can someone please evaluate the problem?
You can use Objective-C literal syntax:
NSNumber *carb = #([self.carbGrams.text floatValue]);
You need to create an object of typ NSNumber from the float. As such
float carb = [self.carbGrams.text floatValue];
NSNumber *nCarb = [NSNumber numberWithFloat: carb];
or why not use the fancy (new) literal syntax
NSNumber *nCarb = #([self.carbGrams.text floatValue]);
Try this:
NSNumber *carb = [NSNumber numberWithFloat:[self.carbGrams.text floatValue]];
I have the following line of code
NSNumber *myValue = loadTempValue*0.420;
where I am trying to set the value of *myValue to the value of loadTempValue*0.420,
However, I get the error
Invalid operands to binary expression ('NSNumber *" and 'double')
Can someone advise how to set this out?
It seems that loadTempValue is also an NSNumber. In that case you want:
NSNumber *myValue = #([loadTempValue doubleValue] * 0.420);
Why are you using NSNumber objects for these values?
If loadTempValue was a double you could just do:
double myValue = loadTempValue * 0.42;
loadTempValue is an NSNumber * and 0.420 is a float. You're trying to multiply an object by a float which the compiler does not understand.
What you want to do it get the float value from loadTempValue and then multiply that by 0.420. You do that this way:
[loadTempValue floatValue] * 0.420;
From there, it seems like you want to put that value back into an NSNumber * object, you do that like this:
#([loadTempValue floatValue] * 0.420);
The #( ... ) syntax was recently introduced to Objective-C. It's called object literal notation for numbers. It is a shorthand way of writing [NSNumber numberWithFloat: ...]
Finally, you will want to assign the result to a variable called myValue; you can accomplish that like this:
NSNumber *myValue = #([loadTempValue floatValue] * 0.420);
Try:
NSNumber *myValue = #([loadTempValue doubleValue] * 0.420);
or
NSNumber *myValue = [NSNumber numberWithDouble:([loadTempValue doubleValue] * 0.420)];
From my understanding of NSNumber, if you create NSNumber with a certain data type, you need to access the variable with that same data type. For example
NSNumber *myIntNumber = [NSNumber numberWithInt:1];
int myInt = [myIntNumber intValue];
NSNumber *myNSIntegerNumber = [NSNumber numberWithInteger:1];
NSInteger myInteger = [myIntNumber integerValue];
If a NSNumber is created using a #define variable:
#define MY_DEFINE 6
does that mean that I cannot do the following
NSNumber *myNSIntegerNumber = [NSNumber numberWithInteger:MY_DEFINE];
NSInteger myInteger = [myIntNumber integerValue];
because MY_DEFINE is not a NSInteger?
I know that the above code would work in a 32-bit app, but I am trying to make sure that it will work on a 64-bit app, which is much more picky about these things, as well. And of course, it never hurts to do things properly.
If I cannot do the above, should I try to define MY_DEFINE differently so that I could use it to create a NSNumber that can later be used to retrieve a NSInteger?
Your understanding of NSNumber is incorrect. You can create an NSNumber with any type it supports and you can then use any of the supported type accessors. The two do not need to the same.
// Perfectly valid
NSNumber *number = [NSNumber numberWithFloat:3.14];
int val = [number intValue]; // results in 3
Your use of the #define is perfectly valid. The pre-compiler simply translates your code to:
NSNumber *myNSIntegerNumber = [NSNumber numberWithInteger:6];
Remember, a #define is nothing more than simple copy and paste (at least in this type of simple form) done before the code is compiled.
You can even use modern syntax:
NSNumber *number = #MY_DEFINE;
which becomes:
NSNumber *number = #6;
BTW - why post this question? Why not just try it first?
When I convert NSNumber to float value using 'floatValue', there is a difference in precision. Example, I have a NSNumber 'myNumber' having value 2.3, and if I convert myNumber to float using 'floatValue', its value becomes, 2.29999. But I need exactly 2.30000. There is no problem with number of zeros after 2.3, I need '2.3' instead of '2.9'.
How can I do so?
I had similar situation where I was reading value and assigning it back to float variable again.
My Problem statement:
NSString *value = #"553637.90";
NSNumber *num = #([value floatValue]); // 1. This is the problem. num is set to 553637.875000
NSNumberFormatter *decimalStyleFormatter = [[NSNumberFormatter alloc] init];
[decimalStyleFormatter setMaximumFractionDigits:2];
NSString *resultString = [decimalStyleFormatter stringFromNumber:num]; // 2. string is assigned with rounded value like 553637.88
float originalValue = [resultString floatValue]; // 3. Hence, originalValue turns out to be 553637.88 which wrong.
Following worked for me after changing lines:
NSNumber *num = #([value doubleValue]); // 4. doubleValue preserves value 553637.9
double originalvalue = [resultString doubleValue]; // 5. While reading back, assign to variable of type double, in this case 'originalValue'
I hope this would be helpful. :)
If you need exact precision, don't use float. Use a double if you need better precision. That still won't be exact. You could multiply myNumber by 10, convert to an unsigned int and perform your arithmetic on it, convert back to a float or double and divide by 10 and the end result might be more precise. If none of these are sufficiently precise, you might want to look into an arbitrary precision arithmetic library such as GNU MP Bignum.
I've done the following but it is showing me correctly
NSNumber *num = [NSNumber numberWithFloat:2.3];
float f = [num floatValue];
NSLog(#"%f", f);
You can play with something like this:
float x = 2.3f;
NSNumber *n = [NSNumber numberWithFloat:x];
NSNumberFormatter *fmt = [[NSNumberFormatter alloc] init];
[fmt setPositiveFormat:#"0.#"];
NSString *s = [fmt stringFromNumber:n];
float f = [s floatValue];