NSString to int loses precision - objective-c

I have a text string that represents a certain value without floating point number:
NSString *value1 = #"20141014135017";
NSString *value2 = #"20141014131024";
int one = [value1 intValue];
int two = [value2 intValue];
Why the result of one and two is only 2147483647? How can I solve this problem?

It depends on the platform, but on a 32-bit platform the limit of int is +/- 2 billion (−2,147,483,648 to 2,147,483,647 to be precise).
Use long instead:
long one = [value1 longValue];
long two = [value2 longValue];

int values can only support a limited number of bits. You should use float or double.
Here is a more comprehensive text on integers link

Related

Objective c min max operation

Can you explain me why this code:
NSInteger i = -1;
NSUInteger x = 1;
NSLog(#"min = %lu", MIN(i, x));
NSLog(#"max = %lu", MAX(i, x));;
prints
min = 1
max = 18446744073709551615
You compare two different types: signed (NSInteger) and unsigned (NSUInteger). MIN/MAX convert all to unsigned integer.
Moreover, negative NSInteger is printed with %lu instead of %du. Therefore see a big number.
NSInteger i = -1;
NSUInteger x = 1;
NSLog(#"min = %ld", MIN(i, (NSInteger)x));
NSLog(#"max = %ld", MAX(i, (NSInteger)x));
It's because i is actually being converted into an unsigned int implicitly. See here. As a result it rolls over to 18446744073709551615.
It is because i is being implicitly converted to an unsigned long. It is part of the way xcode handles integer conversions. Here is a similar post. NSUInteger vs NSInteger, int vs unsigned, and similar cases

Objc: convert unsigned long to float [duplicate]

It might be a simple solution but I can not fix it.
I am dividing 2 integers :
finishedGameFinalScore = [score integerValue];
CGFloat interval = 2/finishedGameFinalScore;
NSLog(#"interval = %f",interval);
The log returns 0.000000
Is there a limit for decimal places? I need to preserve the decimal result.
Thanks
Shani
The reason your code doesn't work is that you're dividing an integer by another integer and then casting the result to a float.
So you have 2 (an integer) and some other number (also an integer). Then you divide 2 by this number - which is probably greater than 2. Let's say it's 3.
Integer sees 2/3 and he's like "0.66666667? Pshh, no one ever needs anything after the decimal point anyway". So he truncates it. You just have 0.
Then Integer gives the number to Mr. float and Mr float is super happy to get a number! He's all like "yay, a 0! I'm going to add ALL OF THE SIGNIFICANT DIGITS". And that's how you end up with 0.0000000.
So yeah, just cast to a float first. Or even a double!
#Dustin said u will need to typecast your divider value to float as it goes in float it shows integer value
CASE 1: Typecast
NSString *score = #"3";
int interval = [str intValue];
CGFloat interval = (2/(float)interval);
NSLog(#"interval = %.2f",interval);
CASE 2: No need for typecast
NSString *score = #"3";
float interval = [str floatValue];
CGFloat interval = (2/interval);
NSLog(#"interval = %.2f",interval);
Just add the f-hint to the number 2. in this case that will do the trick.
CGFloat interval = 2.0f/finishedGameFinalScore;
all the above/below answers are correct and fully explain why this work.
just devide long value from 1.0 and assigned to float variable.
unsigned long l1 = 65536;
unsigned long l2 = 256;
float f = (l1/1.0)/(l2/1.0);
NSLog(#"%f",f);

NSString intValue deforming actual number

I was making a basic method that takes a Flickr image URL and returns the image's ID.
I'm passing the method the NSString #"http://farm6.staticflickr.com/5183/5629026092_c6762a118f".
The goal is to return the int: 5629026092, which is in the image's URL and is the image's ID.
Here is my method:
-(int)getImageIDFromFlickrURL:(NSString *)imageURL{
NSArray *objectsInURLArray = [imageURL componentsSeparatedByString:#"/"];
NSString *lastObjectInFlickrArray = [objectsInURLArray lastObject];
NSArray *dirtyFlickrIdArray = [lastObjectInFlickrArray componentsSeparatedByString:#"_"];
NSString *flickIDString = [dirtyFlickrIdArray objectAtIndex:0];
NSLog(#"flickr id string: %#",flickIDString);
int flickrID = [flickIDString intValue];
NSLog(#"id: %i",flickrID);
return flickrID;
}
The output in the console is:
2012-05-26 13:30:25.771 TestApp[1744:f803] flickr id string: 5629026092
2012-05-26 13:30:25.773 TestApp[1744:f803] id: 2147483647
Why is calling intValue deforming the actual number?
Use long long instead, your number is greater than int can handle (max being 2147483647 as you can see in your second log)
Your value is too big to represent in 32 bits. The biggest value you can store in a signed 32 bit integer (int) is 2147483647. For unsigned ints, it's 4294967295. You need to convert to a long long integer to represent a number as big as 5629026092.
You'll probably need to create a number formatter for that. I'm no expert on number formatters, and always have to dig out the documentation to figure out how to use them.
I just tried it, and this code works:
NSString *numberString = #"5629026092";
NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
NSNumber *number = [formatter numberFromString: numberString];
long long value = [number longLongValue];
NSLog(#"%# = %qi", numberString, value);
[formatter release];
You could also convert the string to a C string and use scanf, come to think of it.
Easy ^^: INT_MAX Maximum value for a variable of type int. 2147483647
I found this to be a convenient way to do it:
NSString *flickIDString = [dirtyFlickrIdArray objectAtIndex:0]; // read some huge number into a string
// read into a NSNumber object or a long long variable. you choose
NSNumber *flickIDNumber = flickIDString.longLongValue;
long long flickIDLong = flickIDString.longLongValue;

How to round an float value and convert it into NSInteger value in the iPhone SDK?

I need to round a float value and convert it into an NSInteger value.
For example:
float f = 90.909088;
I want the result to be 91. How to get rid of this?
A quick round and cast will work for negative values as well as positives:
NSInteger intValue = (NSInteger) roundf(f);
One of the following C math functions might work for you:
double ceil(double)
double floor(double)
double nearbyint(double)
double rint(double)
double round(double)
long int lrint(double)
long int lround(double)
long long int llrint(double)
long long int llround(double)
double trunc(double)
To get more documentation, open a terminal session and type (for example)
man lround
I pick lround as an example because I think that is the one you want.
Do
f = floor(f + 0.5)
before the integer conversion.
Try:
float f = 90.909088;
NSNumber *myNumber = [NSNumber numberWithDouble:(f+0.5)];
NSInteger myInt = [myNumber intValue];

How to convert a string into double and vice versa?

I want to convert a string into a double and after doing some math on it, convert it back to a string.
How do I do this in Objective-C?
Is there a way to round a double to the nearest integer too?
You can convert an NSString into a double with
double myDouble = [myString doubleValue];
Rounding to the nearest int can then be done as
int myInt = (int)(myDouble + (myDouble>0 ? 0.5 : -0.5))
I'm honestly not sure if there's a more streamlined way to convert back into a string than
NSString* myNewString = [NSString stringWithFormat:#"%d", myInt];
To really convert from a string to a number properly, you need to use an instance of NSNumberFormatter configured for the locale from which you're reading the string.
Different locales will format numbers differently. For example, in some parts of the world, COMMA is used as a decimal separator while in others it is PERIOD — and the thousands separator (when used) is reversed. Except when it's a space. Or not present at all.
It really depends on the provenance of the input. The safest thing to do is configure an NSNumberFormatter for the way your input is formatted and use -[NSFormatter numberFromString:] to get an NSNumber from it. If you want to handle conversion errors, you can use -[NSFormatter getObjectValue:forString:range:error:] instead.
Adding to olliej's answer, you can convert from an int back to a string with NSNumber's stringValue:
[[NSNumber numberWithInt:myInt] stringValue]
stringValue on an NSNumber invokes descriptionWithLocale:nil, giving you a localized string representation of value. I'm not sure if [NSString stringWithFormat:#"%d",myInt] will give you a properly localized reprsentation of myInt.
Here's a working sample of NSNumberFormatter reading localized number String (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 such as "8,765.4 ", 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
olliej's rounding method is wrong for negative numbers
2.4 rounded is 2 (olliej's method gets this right)
−2.4 rounded is −2 (olliej's method returns -1)
Here's an alternative
int myInt = (int)(myDouble + (myDouble>0 ? 0.5 : -0.5))
You could of course use a rounding function from math.h
// Converting String in to Double
double doubleValue = [yourString doubleValue];
// Converting Double in to String
NSString *yourString = [NSString stringWithFormat:#"%.20f", doubleValue];
// .20f takes the value up to 20 position after decimal
// Converting double to int
int intValue = (int) doubleValue;
or
int intValue = [yourString intValue];
For conversion from a number to a string, how about using the new literals syntax (XCode >= 4.4), its a little more compact.
int myInt = (int)round( [#"1.6" floatValue] );
NSString* myString = [#(myInt) description];
(Boxes it up as a NSNumber and converts to a string using the NSObjects' description method)
For rounding, you should probably use the C functions defined in math.h.
int roundedX = round(x);
Hold down Option and double click on round in Xcode and it will show you the man page with various functions for rounding different types.
This is the easiest way I know of:
float myFloat = 5.3;
NSInteger myInt = (NSInteger)myFloat;
from this example here, you can see the the conversions both ways:
NSString *str=#"5678901234567890";
long long verylong;
NSRange range;
range.length = 15;
range.location = 0;
[[NSScanner scannerWithString:[str substringWithRange:range]] scanLongLong:&verylong];
NSLog(#"long long value %lld",verylong);
convert text entered in textfield to integer
double mydouble=[_myTextfield.text doubleValue];
rounding to the nearest double
mydouble=(round(mydouble));
rounding to the nearest int(considering only positive values)
int myint=(int)(mydouble);
converting from double to string
myLabel.text=[NSString stringWithFormat:#"%f",mydouble];
or
NSString *mystring=[NSString stringWithFormat:#"%f",mydouble];
converting from int to string
myLabel.text=[NSString stringWithFormat:#"%d",myint];
or
NSString *mystring=[NSString stringWithFormat:#"%f",mydouble];
I ended up using this handy macro:
#define STRING(value) [#(value) stringValue]