簡體   English   中英

將4個原始字節轉換為32位浮點

[英]Converting 4 raw bytes into 32-bit floating point

我正在嘗試從eeprom重建32位浮點值。

eeprom存儲器(0-4)中的4個字節為:B4 A2 91 4D

並且PC(VS Studio)正確地將其重構為3.054199 * 10 ^ 8(我知道的浮點值應該存在)

現在,我將這種eeprom從8位Arduino讀取,因此不確定是否是編譯器/平台的東西,但是當我嘗試將4個字節讀取為32位dword,然后將其類型轉換為float時,我獲得的價值甚至不高。

假設無法使用標准的ansi-c編譯器自動完成轉換,那么如何手動將這4個字節解析為浮點數?

最安全的方法是使用memcpy ,並且由於編譯器的優化也比其他方法快,因此:

uint32_t dword = 0x4D91A2B4;
float f;
memcpy(&f, &dw, 4);

演示: http//ideone.com/riDfFw

正如Shafik Yaghmour在回答中提到的那樣-可能是字節序問題,因為這是您在如此低級別的操作中可能遇到的唯一邏輯問題。 盡管Shafiks回答了他所鏈接的問題,但基本上涵蓋了處理此類問題的過程,但我只為您提供一些信息:

至於在Anduino論壇,Anduino使用小端 如果不確定最終將要使用的系統的字節序,但是想要使代碼成為半多平台平台,則可以在運行時使用簡單的代碼片段檢查字節序:

bool isBigEndian(){
   int number = 1;
   return (*(char*)&number != 1);
}

建議您-消耗所有的處理器時間,並使程序運行緩慢,盡管這幾乎總是一件壞事,但是您仍然可以使用它在應用程序的調試版本中查看結果。

它的工作方式是測試存儲在&number指向的地址處的int的第一個字節。 如果第一個字節不為1 ,則表示字節為Big Endian

同樣-僅在sizeof(int) > sizeof(char)時才有效。

您也可以將其嵌入代碼中:

float getFromEeprom(int address){
   char bytes[sizeof(float)];
   if(isBigEndian()){
      for(int i=0;i<sizeof(float);i++)
         bytes[sizeof(float)-i] = EEPROM.read(address+i);
   }
   else{
      for(int i=0;i<sizeof(float);i++)
         bytes[i] = EEPROM.read(address+i);
   }
   float result;
   memcpy(&result, bytes, sizeof(float));
   return result;
}

您需要在指針級別進行轉換。

int     myFourBytes = /* something */;
float*  myFloat = (float*) &myFourBytes;
cout << *myFloat;

應該管用。

如果數據是在另一個以相反的字節序存儲值的平台上生成的,則需要手動交換字節。 例如:

unsigned char myFourBytes[4] = { 0xB4, 0xA2, 0x91, 0x4D };
std::swap(myFourBytes[0], myFourBytes[3]);
std::swap(myFourBytes[1], myFourBytes[2]);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM