使用c – printf将ieee 754 float转换为hex
理想情况下,以下代码将采用IEEE 754表示forms的浮点数并将其转换为hex
void convert() //gets the float input from user and turns it into hexadecimal { float f; printf("Enter float: "); scanf("%f", &f); printf("hex is %x", f); }
我不太确定会出现什么问题。 它将数字转换为hex数,但却是一个非常错误的数字。
123.1443 gives 40000000 43.3 gives 60000000 8 gives 0
所以它正在做某事,我只是不太确定是什么。
帮助将不胜感激
当您将float
作为参数传递给可变参数函数(如printf()
)时,它会被提升为double
,这是float
两倍(至少在大多数平台上)。
解决这个问题的一种方法是将float
作为参数传递给printf()
时将其转换为unsigned int
:
printf("hex is %x", *(unsigned int*)&f);
这也更正确,因为printf()
使用格式说明符来确定每个参数的大小。
从技术上讲,此解决方案违反了严格的别名规则 。 你可以通过将float
的字节复制到unsigned int
然后将其传递给printf()
:
unsigned int ui; memcpy(&ui, &f, sizeof (ui)); printf("hex is %x", ui);
这两种解决方案都基于sizeof(int) == sizeof(float)
的假设,这是许多32位系统的情况,但不一定是这种情况。
支持时,使用%a将浮点数转换为标准hex格式。 这是我能找到的唯一列出%a选项的文档 。
否则,必须将浮点值的位拉入已知大小的整数类型。 例如,如果您知道float和int都是32位,则可以快速执行:
printf( "%08X" , *(unsigned int*)&aFloat );
如果您希望减少对大小的依赖,可以使用联合:
union { float f; //char c[16]; // make this large enough for any floating point value char c[sizeof(float)]; // Edit: changed to this } u; uf = aFloat; for ( i = 0 ; i < sizeof(float) ; ++i ) printf( "%02X" , uc[i] & 0x00FF );
循环的顺序取决于体系结构字节顺序。 这个例子是大端。
无论哪种方式,浮点格式都可能无法移植到其他架构。 %a选项旨在用于。
HEX to Float
我花了很长时间试图弄清楚如何将HEX输入从格式化为IEE754 float的串行连接转换为float。 现在我明白了。 只是想分享,以防它可以帮助别人。
#include #include int main(int argc, char *argv[]) { uint16_t tab_reg[64] //declare input value recieved from serial connection union IntFloat { int32_t i; float f; }; //Declare combined datatype for HEX to FLOAT conversion union IntFloat val; int i; char buff[50]; //Declare buffer for string i=0; //tab_reg[i]=0x508C; //to test the code without a data stream, //tab_reg[i+1]=0x4369; //you may uncomment these two lines. printf("Raw1: %X\n",tab_reg[i]); //Print raw input values for debug printf("Raw2: %X\n",tab_reg[i+1]); //Print raw input values for debug rs = sprintf(buff,"0X%X%X", tab_reg[i+1], tab_reg[i]); //I need to swap the words, as the response is with the opposite endianness. printf("HEX: %s",buff); //Show the word-swapped string val.i = atof(buff); //Convert string to float :-) printf("\nFloat: %f\n", val.f); //show the value in float }
输出:
Raw1: 508C Raw2: 436A HEX: 0X436A508C Float: 234.314636
这种方法对我来说总是很好:
union converter{ float f_val; unsigned int u_val; }; union converter a; a.f_val = 123.1443f; printf("my hex value %x \n", a.u_val);
愚蠢的例子:
unsigned char* floatToHex(float val){ unsigned char* hexVals = malloc(sizeof(float)); hexVals[0] = ((unsigned char*)&val)[0]; hexVals[1] = ((unsigned char*)&val)[1]; hexVals[2] = ((unsigned char*)&val)[2]; hexVals[3] = ((unsigned char*)&val)[3]; return hexVals; }
当我弄清楚时,这是非常明显的解决方案。 没有必要掩盖,memcpy或其他技巧。
在上面的例子中,它是出于特定目的,我知道浮点数是32位。 如果您不确定系统,可以使用更好的解决方案:
unsigned char* floatToHex(float val){ unsigned char* hexVals = malloc(sizeof(float)); for(int i = 0; i < sizeof(float); i++){ hexVals[i] = ((unsigned char*)&val)[i]; } return hexVals; }
这个怎么样:?
int main(void){ float f = 28834.38282; char *x = (char *)&f; printf("%f = ", f); for(i=0; i
https://github.com/aliemresk/ConvertD2H/blob/master/main.c
将Hex转换为Double将Double转换为Hex
此代码使用IEEE 754浮动格式。
最终对我有用的东西(看似令人费解):
#include int main((int argc, char** argv) { float flt = 1234.56789; FILE *fout; fout = fopen("outFileName.txt","w"); fprintf(fout, "%08x\n", *((unsigned long *)&flt); /* or */ printf("%08x\n", *((unsigned long *)&flt); }