In your code, in function bintofloat()
following address casting and dereferencing is invalid:
float *f = (float *)&x;
return *f;
This will call undefined behavior at runtime.
Do not convert a pointer value to a pointer type that is more strictly aligned than the referenced type. Different alignments are possible for different types of objects. If the type-checking system is overridden by an explicit cast or the pointer is converted to a void pointer (void *)
and then to a different type, the alignment of an object may be changed.
The C Standard, 6.3.2.3, paragraph 7 [ISO/IEC 9899:2011], states:
A pointer to an object or incomplete type may be converted to a pointer to a different object or incomplete type. If the resulting pointer is not correctly aligned for the referenced type, the behavior is undefined.
If the misaligned pointer is dereferenced, the program may terminate abnormally. On some architectures, the cast alone may cause a loss of information even if the value is not dereferenced if the types involved have differing alignment requirements.
In your code x
is unsigned int that has different memory alignments then float types.
Type conversion float *f = (float *)&x;
is valid but not good idea in general. A float type pointer should point to float type. Some systems may even give the program a fatal SIGBUS when deferencing an unsigned int* as a float* because float require more strict address alignment to a multiple of sizeof(float).
When you what to write generic code then approved way to assign address of unknown type is using void*
, but to derefrence you have to convert into correct type back so in fact following code is wrong:
unsigned int x = 10U;
unsigned int *xp = &x;
void* vp = x;
float* fp = vp;
float f = *fp;
The link from where I quoted give you some more examples that will help you to understand the issue.
You should also read this Keith Thompson's answer: What is the difference between float pointer and int pointer address?
Edit: I think you can do something like as below:
#include<stdio.h>
float bintofloat(unsigned int x) {
union {
unsigned int x;
float f;
} temp;
temp.x = x;
return temp.f;
}
int main(){
float f = bintofloat(0x4236AE14U);
printf ("\nf = %f ", f);
printf ("\nf = %f \n", bintofloat(0x4287F0A4U));
return 0;
}
Use it as:
$ gcc -Wall -pedantic binarytofloat.c
taxspanner@:~$ ./a.out
f = 45.669998
f = 67.970001
Check following float Precision IEEE754 calculator's Links:
- 0x4236AE14U
- 0x4287F0A4U