繁体   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