[英]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.