我正在尝试将带有十六进制值的nsstring转换为浮点值。
NSString *hexString = @"3f9d70a4";
浮点值应为= 1.230
。
我试图解决这个问题的一些方法是:
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;
}
结果:
string 0x3f9d70a4
scanner result 1 = 0x1.fceb86p+29 (or 1067282624.000000)
2.广播指针
NSNumber * xPtr = [NSNumber numberWithFloat:[(NSNumber *)@"3f9d70a4" floatValue]];
结果:3.000000
答案 0 :(得分:3)
你所拥有的不是“十六进制浮点数”,由%a
字符串格式生成并由scanHexFloat:
扫描,但是是32位浮点值的十六进制表示 - 即实际位。
要将其转换回C中的浮点,需要弄乱类型系统 - 让您访问构成浮点值的字节。您可以使用union
:
typedef union { float f; uint32_t i; } FloatInt;
此类型与struct
类似,但字段重叠在一起。您应该明白,进行这种操作需要您了解存储格式,了解字节顺序等。不要轻易做到这一点。
现在您具有上述类型,您可以扫描十六进制整数并将结果字节解释为浮点数:
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
}
这很有效,但请再仔细考虑一下你在做什么。
HTH
答案 1 :(得分:1)
我认为更好的解决方案是这样的解决方法:
-(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);;
}
你的参数是一个NSData,它以十六进制格式表示数字,输入参数是一个指向NSData元素的指针。
答案 2 :(得分:0)
因此,基本上,您正在尝试使C的NSString
成为float
,这是一种古老的方式!
NSString* hexString = @"3f9d70a4";
const char* cHexString = [hexString UTF8String];
long l = strtol(cHexString, NULL, 16);
float f = *((float *) &l);
// f = 1.23
有关更多详细信息,请参见this answer