Reputation: 49
I have a function for fp16 to fp32 conversion
static float fp16_to_fp32(const short in){
signed int t1, t2, t3;
float out = 0;
t1 = (in & 0x7fff) << 13 + 0x38000000;
t2 = (in & 0x8000) << 16;
t3 = in & 0x7c00;
t1 = (t3==0 ? 0 : t1);
t1 |= t2;
*((unsigned int*)&out) = t1;
return out;
}
error: dereferencing typed-punned pointer will break strict-aliasing rules [-Werror=strict-aliasing] in ((unsigned int)&out) = t1;
How can I solve this? (can't change type of argument in
)
Upvotes: 0
Views: 200
Reputation: 214780
You can use type punning through union
to dodge strict aliasing:
union type_punner
{
unsigned int i;
float f;
} out = {.i = t1};
return out.f;
This assuming int and float are the same size, so it isn't very portable code.
You could also compile with -fno-strict-aliasing
.
Upvotes: 1
Reputation: 75062
You can use memcpy()
for copying data.
Also note that +
operator has higher precedence than <<
operator, so the line t1 = (in & 0x7fff) << 13 + 0x38000000;
won't work as expected.
#include <string.h> /* for memcpy() */
static float fp16_to_fp32(const short in){
signed int t1, t2, t3;
float out = 0;
t1 = ((in & 0x7fff) << 13) + 0x38000000; /* add parenthesis */
t2 = (in & 0x8000) << 16;
t3 = in & 0x7c00;
t1 = (t3==0 ? 0 : t1);
t1 |= t2;
memcpy(&out, &t1, sizeof(out)); /* use memcpy() for copying */
return out;
}
Upvotes: 4