2014-05-02 217 views
-1

我正在尝试将十六进制值的nsstring转换为浮点值。将十六进制字符串转换为IEEE 754浮点数

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.casting指针

NSNumber * xPtr = [NSNumber numberWithFloat:[(NSNumber *)@"3f9d70a4" floatValue]]; 

结果: 3.000000

+0

这与Xcode无关。 – nhgrif

+0

这是我工作的平台,所以我认为它可能会有用。你知道如何解决我的问题吗? – ribbit

+0

你应该向我们展示你的尝试。事实上,如果您使用xcode或任何其他IDE编写代码,则无关紧要。 – vikingosegundo

回答

3

你有什么不是一个“十六进制浮点数”,由%a字符串格式产生,并且由scanHexFloat:扫描,而是32位浮点值的十六进制表示 - 即实际位。

要将此转换回C语言中的float,需要与类型系统混合 - 让您访问组成浮点值的字节。你可以用union做到这一点:

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

这种类型类似于struct但字段都在彼此的顶部覆盖。你应该明白,做这种操作需要你了解存储格式,了解endian命令等。不要轻易做这件事。

现在你有以上类型可以扫描十六进制整数和解释结果字节的浮点数:

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

+0

非常感谢!我知道endian命令。我以前从来没有意识到工会。 – ribbit

+0

我想写这个转换的swift 2.0等价物,但无法找到'union'的swift转换 – Singh

+0

@ mach5 - Swift没有相当于'union',它违背了Swift强壮的打字模式。您的选择包括:尝试使用不安全指针的Swift解决方案;并简单地调用(Objective-)C代码来完成这项工作。 – CRD

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其rapresents输入参数HEX格式的数量,并且是一个指针NSData的元素。

相关问题