Reputation: 131
I have a problem with converting unsigned long to Float single precision Here is my problem
I need to communicate in floating point in my program, but all my internal variables are unsigned long, So the design we decided was such that everything will remain same,(in unsigned long) and once a float needs to be given to application, i will convert to float and pass it on.
So all the variables will have a IEEE 754 bit stream according to
Steps i follow :
In debugger i see the same bit pattern (in buffers) for steps 1 &2
In step 3 too, i see the same binary pattern, but the value is not interpreted as a float
Input : 21.125
Decimal: 1101594624
Code:
void ApplicationApi(void * DataPtr)
{
(*(float32*)((void*)DataPtr))= unsignedLong_val;
}
Result in application DataPtr * DataPtr = 1.101594624 * e9
Am i missing something here or the type case worked ?
Upvotes: 0
Views: 1607
Reputation: 222679
A standard C way to reinterpret the bytes of an unsigned long
as a float
is:
y = (union { unsigned long u; float f; }) { x } .f;
This code defines a compound literal that is a union, and it initializes the union with the value of x
, which should be an unsigned long
. Then it accesses the f
member of the union, which is a float
. This float
value is assigned to y
, which should be a float
.
Thus, assuming the declaration of ApplicationApi
must remain the same and that the void *DataPtr
it is passed is the result of converting a pointer to a float
to a pointer to void
, its definition could be:
void ApplicationApi(void *DataPtr)
{
* (float32 *) DataPtr =(union { unsigned long u; float32 f; }) { unsignedLong_val } .f;
}
Notes about this code:
unsigned long
and float32
have the same size.unsignedLong_val
to have file scope. It would be preferable to pass it as a parameter.void *
. It could be passed as a float32 *
.Notes about code leading up to this code:
unsigned long
may have endian issues.unsigned long
could have trap values that prevent it from being used to hold arbitrary bytes.About the C standard and reinterpreting bytes:
.
operator and a member name has the value of the named member. Note 95 of the standard indicates that this may be used to reinterpret bytes.memcpy
is sometimes used for this.)Upvotes: 0
Reputation: 2584
Try with this cast :
void ApplicationApi(void * DataPtr)
{
*(float32*)DataPtr = *(float32*)unsignedLong_val;
}
You have to declare that the right value is a float value.
With your cast, the right value is an integer and the left value a float. The compiler convert implicitly the integer to a float value.
Upvotes: -1