理想情况下,以下代码将采用IEEE 754表示形式的浮点数并将其转换为十六进制
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);
}
我不太确定会出现什么问题。它将数字转换为十六进制数,但却是一个非常错误的数字。
123.1443 gives 40000000
43.3 gives 60000000
8 gives 0
所以它正在做某事,我只是不太确定是什么。
帮助将不胜感激
答案 0 :(得分:26)
当您将float
作为参数传递给可变参数函数(如printf()
)时,会将其提升为double
,这是float
的两倍大(至少在大多数平台上)。
解决此问题的一种方法是将float
转换为unsigned int
,并将其作为参数传递给printf()
:
printf("hex is %x", *(unsigned int*)&f);
这也更正确,因为printf()
使用格式说明符来确定每个参数的大小。
从技术上讲,此解决方案违反了strict aliasing rule。你可以通过将float
的字节复制到unsigned int
然后将其传递给printf()
来解决这个问题:
unsigned int ui;
memcpy(&ui, &f, sizeof (ui));
printf("hex is %x", ui);
这两种解决方案都基于sizeof(int) == sizeof(float)
的假设,这是许多32位系统的情况,但不一定如此。
答案 1 :(得分:12)
支持时,使用%a将浮点数转换为标准十六进制格式。这是我能找到的唯一列出%a选项的document。
否则,您必须将浮点值的位拉入已知大小的整数类型。例如,如果您知道float和int都是32位,则可以快速执行:
printf( "%08X" , *(unsigned int*)&aFloat );
如果您希望减少对大小的依赖,可以使用union:
union {
float f;
//char c[16]; // make this large enough for any floating point value
char c[sizeof(float)]; // Edit: changed to this
} u;
u.f = aFloat;
for ( i = 0 ; i < sizeof(float) ; ++i ) printf( "%02X" , u.c[i] & 0x00FF );
循环的顺序取决于体系结构字节顺序。这个例子是大端。
无论哪种方式,浮点格式都可能无法移植到其他架构。 %a选项旨在用作。
答案 2 :(得分:3)
HEX to Float
我花了很长时间试图弄清楚如何将HEX输入从格式化为IEE754 float的串行连接转换为float。现在我明白了。只是想分享,以防它可以帮助其他人。
#include <stdio.h>
#include <stdlib.h>
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
答案 3 :(得分:2)
这种方法对我来说总是很好:
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);
答案 4 :(得分:2)
愚蠢的例子:
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;
}
答案 5 :(得分:1)
这个怎么样??
int main(void){
float f = 28834.38282;
char *x = (char *)&f;
printf("%f = ", f);
for(i=0; i<sizeof(float); i++){
printf("%02X ", *x++ & 0x0000FF);
}
printf("\n");
}
答案 6 :(得分:1)
https://github.com/aliemresk/ConvertD2H/blob/master/main.c
将Hex转换为Double 将Double转换为Hex
此代码使用IEEE 754浮动格式。
答案 7 :(得分:0)
最终对我有用的东西(看起来很复杂):
#include <stdio.h>
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);
}