C++ Float32 与 Float16 互转

这段代码提供了将float32类型浮点数转换为float16以及将float16转换回float32的函数实现。转换过程中涉及符号位、指数和尾数的处理,包括对NaN和Inf的特殊处理。函数使用memcpy_s进行内存操作,并有错误检查机制。
摘要由CSDN通过智能技术生成

 float32转float16

void Float32ToFloat16(uint16_t *result, float fp)
{
    if (fp > FP16_MAX) {
        (*result) = 0x7fff;
        return;
    } else if (fp < (-FP16_MAX)) {
        *result = 0xffff;
        return;
    } else if (fp < FP16_MIN && fp > (-FP16_MIN)) {
        *result = 0;
        return;
    }
    uint32_t fpBit = 0;
    int32_t ret = memcpy_s(&fpBit, sizeof(uint32_t), &fp, sizeof(float));
    LOG_IF_FAIL(ret == 0, "Float32ToFloat16 memcpy_s error %d", ret);
    uint32_t sign = ((fpBit >> 31) & 1);
    uint32_t exponent = ((fpBit >> 23) & 0xff);
    uint32_t fraction = ((fpBit >> 13) & 0x3ff);
    while(exponent < 0x71) {
        fraction >>= 1;
        exponent += 1;
    }
    exponent -= 0x70;
    *result = ((sign << 15) | (exponent << 10) | fraction);
    return;
}

之前用了ChatGPT生成,经提醒似乎是错的,已更新

float16转float32

void Float16ToFloat32(float *result, uint16_t halfFloat)
{
    // 符号+指数+尾数 FP16: 1+5+10 FP32: 1+8+23
    uint32_t sign = ((halfFloat >> 15) & 1);                // 15: 符号位
    uint32_t exponent = ((halfFloat >> 10) & 0x1f);         // 10: 去除尾数
    uint32_t fraction = ((halfFloat & 0x3ff) << 13);        // 13: fp32与fp16尾数位数差  0x3ff: 2^10-1,取位数
    if (exponent == 0x1f) {
        // nan或inf,除符号位外全1
        fraction = (fraction ? (sign = 0, 0x7fffff) : 0);   // 0x7fffff: 2^23-1
        exponent = 0xff;                                    // 0xff: 2^8-1
    } else if (!exponent) {
        // zero或denorm,指数为0
        if (fraction) {
            // not zero
            uint32_t m;
            exponent = 0x71;                                // 0x71: 2^7-2^4+1,指数移码差值+1
            do {
                m = (fraction & 0x400000);                  // 0x400000: 2^(23-1),取fraction的第一个非0位
                fraction <<= 1;
                --exponent;
            } while (!m);
            fraction &= 0x7fffff;                           // 0x7fffff: 2^23-1
        }
    } else {
        exponent += 0x70;                                   // 0x70: 2^7-2^4,指数移码差值
    }
    uint32_t temp = ((sign << 31) | (exponent << 23) | fraction);
    int32_t ret = memcpy_s(&result, sizeof(float), &temp, sizeof(uint32_t));
    LOG_IF_FAIL(ret == 0, "Float16ToFloat32 memcpy_s error %d", ret);
    return;
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值