45 lines
1.1 KiB
C++
45 lines
1.1 KiB
C++
#include "parquet_float16.hpp"
|
|
|
|
#include "duckdb.hpp"
|
|
|
|
namespace duckdb {
|
|
|
|
float Float16ToFloat32(const uint16_t &float16_value) {
|
|
uint32_t sign = float16_value >> 15;
|
|
uint32_t exponent = (float16_value >> 10) & 0x1F;
|
|
uint32_t fraction = (float16_value & 0x3FF);
|
|
// Avoid strict aliasing issues and compiler warnings
|
|
uint32_t float32_value = 0;
|
|
|
|
if (exponent == 0) {
|
|
if (fraction == 0) {
|
|
// zero
|
|
float32_value = (sign << 31);
|
|
} else {
|
|
// can be represented as ordinary value in float32
|
|
// 2 ** -14 * 0.0101
|
|
// => 2 ** -16 * 1.0100
|
|
// int int_exponent = -14;
|
|
exponent = 127 - 14;
|
|
while ((fraction & (1 << 10)) == 0) {
|
|
// int_exponent--;
|
|
exponent--;
|
|
fraction <<= 1;
|
|
}
|
|
fraction &= 0x3FF;
|
|
// int_exponent += 127;
|
|
float32_value = (sign << 31) | (exponent << 23) | (fraction << 13);
|
|
}
|
|
} else if (exponent == 0x1F) {
|
|
/* Inf or NaN */
|
|
float32_value = (sign << 31) | (0xFF << 23) | (fraction << 13);
|
|
} else {
|
|
/* ordinary number */
|
|
float32_value = (sign << 31) | ((exponent + (127 - 15)) << 23) | (fraction << 13);
|
|
}
|
|
|
|
return Load<float>(const_data_ptr_cast(&float32_value));
|
|
}
|
|
|
|
} // namespace duckdb
|