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