在 C++ 中将 FP32 转换为 Bfloat16

oaw*_*wad 7 c++ floating-point

如何在 C++ 中从 float(1 位符号、8 位 exp、23 位尾数)转换为 Bfloat16(1 位符号、8 位 exp、7 位尾数)?

Mar*_*som 5

正如Botje 的答案所示,复制该值的上半部分就足够了,float因为位模式是相同的。该答案的完成方式违反了 C++ 中严格别名的规则。解决这个问题的方法是使用memcpy复制位。

static inline tensorflow::bfloat16 FloatToBFloat16(float float_val)
{
    tensorflow::bfloat16 retval;
#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
    memcpy(&retval, &float_val, sizeof retval);
#else
    memcpy(&retval, reinterpret_cast<char *>(&float_val) + sizeof float_val - sizeof retval, sizeof retval);
#endif
    return retval;
}
Run Code Online (Sandbox Code Playgroud)

如果需要对结果进行舍入而不是截断,您可以乘以一个幻值,将其中一些较低位推入较高位。

float_val *= 1.001957f;
Run Code Online (Sandbox Code Playgroud)


Bot*_*tje 1

Tensorflow 实现来看

static inline tensorflow::bfloat16 FloatToBFloat16(float float_val) {
#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
    return *reinterpret_cast<tensorflow::bfloat16*>(
        reinterpret_cast<uint16_t*>(&float_val));
#else
    return *reinterpret_cast<tensorflow::bfloat16*>(
        &(reinterpret_cast<uint16_t*>(&float_val)[1]));
#endif
}
Run Code Online (Sandbox Code Playgroud)