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...
Related
I have an 8 bit Hex Value like: "FB" (-5). Now I need an signed integer value for this hex. The NSScanner don't work on this place, because you need an 4 Byte hex value, to get it negative. Before I start some bit manipulation, maybe someone of you know the better way to do that?
Type casting is not safe but you really need it.
NSString *tempNumber = #"FB";
NSScanner *scanner = [NSScanner scannerWithString:tempNumber];
unsigned int temp;
[scanner scanHexInt:&temp];
int actualInt = (char)temp; //why char because you have 8 bit integer
NSLog(#"%#:%d:%d",tempNumber, temp, actualInt);
Console output: FB:251:-5
I am trying to convert a nsstring with hex values into a float value.
NSString *hexString = #"3f9d70a4";
The float value should be = 1.230.
Some ways I have tried to solve this are:
1.NSScanner
-(unsigned int)strfloatvalue:(NSString *)str
{
float outVal;
NSString *newStr = [NSString stringWithFormat:#"0x%#",str];
NSScanner* scanner = [NSScanner scannerWithString:newStr];
NSLog(#"string %#",newStr);
bool test = [scanner scanHexFloat:&outVal];
NSLog(#"scanner result %d = %a (or %f)",test,outVal,outVal);
return outVal;
}
results:
string 0x3f9d70a4
scanner result 1 = 0x1.fceb86p+29 (or 1067282624.000000)
2.casting pointers
NSNumber * xPtr = [NSNumber numberWithFloat:[(NSNumber *)#"3f9d70a4" floatValue]];
result:3.000000
What you have is not a "hexadecimal float", as is produced by the %a string format and scanned by scanHexFloat: but the hexadecimal representation of a 32-bit floating-point value - i.e. the actual bits.
To convert this back to a float in C requires messing with the type system - to give you access to the bytes that make up a floating-point value. You can do this with a union:
typedef union { float f; uint32_t i; } FloatInt;
This type is similar to a struct but the fields are overlaid on top of each other. You should understand that doing this kind of manipulation requires you understand the storage formats, are aware of endian order, etc. Do not do this lightly.
Now you have the above type you can scan a hexadecimal integer and interpret the resultant bytes as a floating-point number:
FloatInt fl;
NSScanner *scanner = [NSScanner scannerWithString:#"3f9d70a4"];
if([scanner scanHexInt:&fl.i]) // scan into the i field
{
NSLog(#"%x -> %f", fl.i, fl.f); // display the f field, interpreting the bytes of i as a float
}
else
{
// parse error
}
This works, but again consider carefully what you are doing.
HTH
I think a better solutions is a workaround like this :
-(float) getFloat:(NSInteger*)pIndex
{
NSInteger index = *pIndex;
NSData* data = [self subDataFromIndex:&index withLength:4];
*pIndex = index;
uint32_t hostData = CFSwapInt32BigToHost(*(const uint32_t *)[data bytes]);
return *(float *)(&hostData);;
}
Where your parameter is an NSData which rapresents the number in HEX format, and the input parameter is a pointer to the element of NSData.
So basically you are trying to make an NSString to C's float, there's an old fashion way to do that!
NSString* hexString = #"3f9d70a4";
const char* cHexString = [hexString UTF8String];
long l = strtol(cHexString, NULL, 16);
float f = *((float *) &l);
// f = 1.23
for more detail please see this answer
Try this:
unsigned long long int N; = 23229877463LL;
NSString* s = [NSString stringWithFormat:#"dec:%qi, hex:%qX",N,N];
NSLog(#"output: %#",s);
output: dec:23229877460, hex:689BCCD400000005
What's up with the 00000005??? In mySQL, hex(23229877460) = 5689BCCD4. Also, every other language seems to do this correctly. A 16 digit long hex is like 4 gazillion (16^16), right?
How can I get objective-c to format hex numbers that other languages can understand?
After fixing the spurious ; to yield:
unsigned long long int N = 23229877463LL;
NSString* s = [NSString stringWithFormat:#"dec:%qi, hex:%qX",N,N];
NSLog(#"output: %#",s);
The code works exactly as expected:
2011-01-09 10:46:16.236 dfjkdfkjfdjkfd[25716:a0f] output: dec:23229877463, hex:5689BCCD7
There is something else wrong. You'll need to post more code. The line used to compile the file would probably be helpful, too.
And for giggles:
unsigned long long int N = 23229877460LL;
NSString* s = [NSString stringWithFormat:#"dec:%qi, hex:%qX",N,N];
2011-01-09 10:49:10.425 dfjkdfkjfdjkfd[25755:a0f] output: dec:23229877460, hex:5689BCCD4
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]..
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);