-1

我正在尝试将具有十六进制值的 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

4

3 回答 3

3

您所拥有的不是“十六进制浮点数”,它由%a字符串格式生成并由scanHexFloat:32 位浮点值的十六进制表示形式扫描 - 即实际位。

要将其转换回 C 中的浮点数,需要弄乱类型系统 - 让您可以访问构成浮点值的字节。您可以使用以下命令执行此操作union

typedef union { float f; uint32_t i; } FloatInt;

此类型与 a 类似,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
}

这行得通,但再次仔细考虑你在做什么。

高温高压

于 2014-05-02T03:06:54.687 回答
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,它以 HEX 格式表示数字,输入参数是一个指向 NSData 元素的指针。

于 2014-12-11T16:45:51.150 回答
0

所以基本上你是在尝试做一个NSStringto C's float,有一种老式的方法可以做到这一点!

NSString* hexString = @"3f9d70a4";
const char* cHexString = [hexString UTF8String];
long l = strtol(cHexString, NULL, 16);
float f = *((float *) &l);
// f = 1.23

有关更多详细信息,请参阅此答案

于 2020-07-21T09:20:49.303 回答