Convert hex string to long - objective-c

Are there any Cocoa classes that will help me convert a hex value in a NSString like 0x12FA to a long or NSNumber? It doesn't look like any of the classes like NSNumberFormatter support hex numbers.
Thanks,
Hua-Ying

Here's a short example of how you would do it using NSScanner:
NSString* pString = #"0xDEADBABE";
NSScanner* pScanner = [NSScanner scannerWithString: pString];
unsigned int iValue;
[pScanner scanHexInt: &iValue];

See NSScanner's scanHex...: methods. That'll get you the primitive that you can wrap in an NSNumber.

here is the other way conversion, a long long int to hex string.
first the hex to long long.
NSString* pString = #"ffffb382ddfe";
NSScanner* pScanner = [NSScanner scannerWithString: pString];
unsigned long long iValue2;
[pScanner scanHexLongLong: &iValue2];
NSLog(#"iValue2 = %lld", iValue2);
and the other way, longlong to hex string...
NSNumber *number;
NSString *hexString;
number = [NSNumber numberWithLongLong:iValue2];
hexString = [NSString stringWithFormat:#"%qx", [number longLongValue]];
NSLog(#"hexString = %#", hexString);

Related

Objective-C: Convert Hex Strings to Integers to Compare Which is Greater

My goal is to compare two hex strings and determine which number is higher. I assume I need to convert those hex strings to integers to be able to compare them mathematically, but the conversion to unsigned isn't working. Here's what I've tried:
NSString *firstHex = #"35c1f029684fe";
NSString *secondHex = #"35c1f029684ff";
unsigned first = 0;
unsigned second = 0;
NSScanner *firstScanner = [NSScanner scannerWithString:firstHex];
NSScanner *secondScanner = [NSScanner scannerWithString:secondHex];
[firstScanner scanHexInt:&first];
[secondScanner scanHexInt:&second];
NSLog(#"First: %d",first);
NSLog(#"Second: %d",second);
But the log output gives me:
First: -1
Second: -1
I can't figure out what I'm doing wrong. Am I using NSScanner correctly here? Thanks in advance.
Your hex numbers are 13 digits long - 52 binary bits. This is longer than 32 bits, use long long variables and scanHexLongLong: instead.
For the sake of completeness, here's the working code using the advice from the above answer:
NSString *firstHex = #"35c1f029684fe";
NSString *secondHex = #"35c1f029684ff";
unsigned long long first = 0;
unsigned long long second = 0;
NSScanner *firstScanner = [NSScanner scannerWithString:firstHex];
NSScanner *secondScanner = [NSScanner scannerWithString:secondHex];
[firstScanner scanHexLongLong:&first];
[secondScanner scanHexLongLong:&second];
NSLog(#"First: %llu",first);
NSLog(#"Second: %llu",second);
if(first > second){
NSLog(#"First is greater");
}else{
NSLog(#"Second is greater");
}
it must be faster to just find out which one is larger as a string:
the longer string is bigger (ignoring leading 0's)
if they are the same then you can convert each char and compare, Repeat for each char...

parsing NSString to Double

so I want to convert NSString to double. I found the following example:
NSString * s = #"1.5e5";
NSLog(#"%lf", [s doubleValue]);
It works but if doubleValue cannot convert the string to double it simply returns 0.0 which is not what I need. I need some method that tries to convert a string representation of double to double and if indicate somehow if it can't be converted.
c# has an excellent method
double d;
boolean Double.TryParse(str, out d)
Is there any method similar to the above one in Objective C? or maybe it's better to use regex? however, i don't really know how to do that.
You can use the NSScanner class:
NSString *s = #"1.5e5";
NSScanner *scanner = [NSScanner scannerWithString:s];
double d;
BOOL success = [scanner scanDouble:&d];
If you want to ensure that the entire string has been scanned (no extra characters after the number), use
BOOL isAtEnd = [scanner isAtEnd];

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;

Byte to int, float, NSString conversion

Are there any methods in objective C for converting byte to int, float and NSString?
The first are C-types. No conversion is needed, just assign them:
byte b = ...;
int x = b;
float f = b;
Converting to NSString could be done using stringWithFormat:, a NSNumberFormatter and many more methods. This is the easiest:
NSString *myString = [NSString stringWithFormat: #"%d", b];
If you want it printed in hex, use #"%x" (for lowercase letters) or #"%X" (for capital letters) instead.
You could get an NSString from NSData with initWithData:encoding: and then transform it into int or float by calling intValue and floatValue

NSString to NSUInteger

I've got a number in a NSString #"15". I want to convert this to NSUInteger, but I don't know how to do that...
NSString *str = #"15";
// Extract an integer number, returns 0 if there's no valid number at the start of the string.
NSInteger i = [str integerValue];
If you really want an NSUInteger, just cast it, but you may want to test the value beforehand.
The currently chosen answer is incorrect for NSUInteger. As Corey Floyd points out a comment on the selected answer this won't work if the value is larger than INT_MAX. A better way of doing this is to use NSNumber and then using one of the methods on NSNumber to retrieve the type you're interested in, e.g.:
NSString *str = #"15"; // Or whatever value you want
NSNumber *number = [NSNumber numberWithLongLong: str.longLongValue];
NSUInteger value = number.unsignedIntegerValue;
All these answers are wrong on a 64-bit system.
NSScanner *scanner = [NSScanner scannerWithString:#"15"];
unsigned long long ull;
if (![scanner scanUnsignedLongLong:&ull]) {
ull = 0; // Or handle failure some other way
}
return (NSUInteger)ull; // This happens to work because NSUInteger is the same as unsigned long long at the moment.
Test with 9223372036854775808, which won't fit in a signed long long.
you can try with [string longLongValue] or [string intValue]..