2014-05-02 254 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的元素。

相關問題