【问题标题】:Convert Hex string to IEEE 754 float将十六进制字符串转换为 IEEE 754 浮点数
【发布时间】:2014-06-18 15:40:00
【问题描述】:

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

【问题讨论】:

  • 这与Xcode无关。
  • 这是我正在工作的平台,所以我认为它可能有用。你知道如何解决我的问题吗?
  • 您应该向我们展示您的尝试。确实,使用 xcode 或任何其他 IDE 编写代码都没有关系。

标签: objective-c nsstring hex cgfloat


【解决方案1】:

所以基本上你是在尝试将NSString 转换为 C 的 float,这是一种老式的方法!

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

更多详情请查看this answer

【讨论】:

    【解决方案2】:

    您所拥有的不是“十六进制浮点数”,它由%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

    【讨论】:

    • 非常感谢!我知道字节序。我以前从不知道工会。
    • 我正在尝试为此转换编写 swift 2.0 等效项,但无法找到 'union' 的快速转换
    • @mach5 - Swift 没有 union 的等价物,它违背了 Swift 的强类型模型。您的选择包括:尝试使用不安全指针的 Swift 解决方案;并简单地调用(Objective-)C 代码来完成这项工作。
    【解决方案3】:

    我认为更好的解决方案是这样的解决方法:

    -(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 元素的指针。

    【讨论】:

      猜你喜欢
      • 2018-08-19
      • 2016-04-02
      • 1970-01-01
      • 2011-02-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-18
      • 1970-01-01
      相关资源
      最近更新 更多