如何在C ++中将float(1bit sign,8bit exp,23bit尾数)转换为Bfloat16(1bit sign,8bit exp,7bit尾数)?
答案 0 :(得分:1)
如answer by 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;
}
如果有必要舍入而不是舍弃结果,可以乘以一个魔术值,将其中一些低位压入高位。
float_val *= 1.001957f;
答案 1 :(得分:1)
memcpy在小端序情况下不会为我编译。这是我的解决方案。 我在这里将其作为结构,以便可以轻松访问数据并运行不同范围的值以确认其正常工作。
struct bfloat16{
unsigned short int data;
public:
bfloat16(){
data = 0;
}
//cast to float
operator float(){
unsigned int proc = data<<16;
return *reinterpret_cast<float*>(&proc);
}
//cast to bfloat16
bfloat16& operator =(float float_val){
data = (*reinterpret_cast<unsigned int *>(&float_val))>>16;
return *this;
}
};
//an example that enumerates all the possible values between 1.0f and 300.0f
using namespace std;
int main(){
bfloat16 x;
for(x = 1.0f; x < 300.0f; x.data++){
cout<<x.data<<" "<<x<<endl;
}
return 0;
}
答案 2 :(得分:0)
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
}