首页 > 解决方案 > fp16 到 fp32 转换的严格别名错误

问题描述

我有 fp16 到 fp32 转换的功能

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;
}

错误:取消引用 typed-punned 指针将破坏严格别名规则 [-Werror=strict-aliasing] in ((unsigned int )&out) = t1;

我该如何解决这个问题?(不能改变参数的类型in

标签: cstrict-aliasingtype-punning

解决方案


您可以memcpy()用于复制数据。

另请注意,+运算符的优先级高于<<运算符,因此该行t1 = (in & 0x7fff) << 13 + 0x38000000;不会按预期工作。

#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;
}

推荐阅读