Half-precision floating point serialization.
This commit is contained in:
@@ -15,6 +15,11 @@ namespace CaveGame::Core
|
||||
uint8_t* data;
|
||||
};
|
||||
|
||||
/// Converts a 16-bit unsigned integer into a floating point number. @see float_to_u16.
|
||||
float u16_to_float(uint16_t value);
|
||||
/// Converts a floating point number to a 16-bit unsigned integer. This in effect, drops the accuracy of the float in exchange for compression.
|
||||
uint16_t float_to_u16(float);
|
||||
|
||||
/// Writes a 1-byte unsigned int to the buffer, in network-byte-order, and advances the index by 1.
|
||||
void write_u8(Buffer& buffer, uint8_t value);
|
||||
/// Writes a 2-byte unsigned int to the buffer, in network-byte-order, and advances the index by 2.
|
||||
@@ -51,11 +56,13 @@ namespace CaveGame::Core
|
||||
/// Reads a 8-byte signed int from the buffer, from network-byte-order, and advances the index by 8.
|
||||
int64_t read_s64(Buffer& buffer);
|
||||
|
||||
void write_f16(Buffer& buffer, float value);
|
||||
/// Writes a 4-byte float to the buffer, via reinterpreting as uint32_t, and advances the index by 4.
|
||||
void write_f32(Buffer& buffer, float value);
|
||||
/// Writes a 8-byte float to the buffer, via reinterpreting as uint64_t, and advances the index by 8.
|
||||
void write_f64(Buffer& buffer, double value);
|
||||
|
||||
float read_f16(Buffer& buffer);
|
||||
/// Reads a 4-byte float from the buffer, via reinterpreting from uint32_t, and advances the index by 4.
|
||||
float read_f32(Buffer& buffer);
|
||||
/// Reads a 8-byte float from the buffer, via reinterpreting from uint64_t, and advances the index by 8.
|
||||
|
@@ -156,6 +156,33 @@ namespace CaveGame::Core
|
||||
|
||||
using J3ML::ReinterpretAs;
|
||||
|
||||
float u16_to_float(uint16_t value)
|
||||
{
|
||||
union {
|
||||
float f_number;
|
||||
uint16_t uint16_arr[2];
|
||||
} union_for_conv;
|
||||
union_for_conv.f_number = 0;
|
||||
union_for_conv.uint16_arr[1] = value;
|
||||
return union_for_conv.f_number;
|
||||
}
|
||||
|
||||
uint16_t float_to_u16(float value)
|
||||
{
|
||||
union {
|
||||
float f_number;
|
||||
uint16_t uint16_arr[2];
|
||||
} union_for_conv;
|
||||
union_for_conv.f_number = value;
|
||||
uint16_t a = union_for_conv.uint16_arr[1];
|
||||
return a;
|
||||
}
|
||||
|
||||
void write_f16(Buffer& buffer, float value)
|
||||
{
|
||||
write_u16(buffer, float_to_u16(value));
|
||||
}
|
||||
|
||||
void write_f32(Buffer &buffer, float value) {
|
||||
write_u32(buffer, ReinterpretAs<uint32_t>(value));
|
||||
}
|
||||
@@ -164,6 +191,10 @@ namespace CaveGame::Core
|
||||
write_u64(buffer, ReinterpretAs<uint64_t>(value));
|
||||
}
|
||||
|
||||
float read_f16(Buffer& buffer) {
|
||||
return u16_to_float(read_u16(buffer));
|
||||
}
|
||||
|
||||
float read_f32(Buffer &buffer) {
|
||||
return ReinterpretAs<float>(read_u32(buffer));
|
||||
}
|
||||
|
@@ -163,6 +163,16 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
void rtt_f16(float input)
|
||||
{
|
||||
uint16_t intermediate = float_to_u16(input);
|
||||
|
||||
float returned = u16_to_float(intermediate);
|
||||
|
||||
std::cout << "Input: " << input << ", Output: " << returned << std::endl;
|
||||
}
|
||||
|
||||
void roundtrip_test()
|
||||
{
|
||||
using namespace CaveGame::Core;
|
||||
@@ -187,18 +197,25 @@ void roundtrip_test()
|
||||
write_u32(test, c);
|
||||
write_u64(test, d);
|
||||
write_s8(test, e);
|
||||
write_f32(test, f);
|
||||
write_f16(test, f);
|
||||
write_string(test, tetsuo);
|
||||
|
||||
test.index = 0;
|
||||
|
||||
a = read_u8(test);
|
||||
a = read_u8(test);
|
||||
b = read_u16(test);
|
||||
c = read_u32(test);
|
||||
d = read_u64(test);
|
||||
e = read_s8(test);
|
||||
f = read_f32(test);
|
||||
uint8_t a_retrieved = read_u8(test);
|
||||
a_retrieved = read_u8(test);
|
||||
uint16_t b_retrieved = read_u16(test);
|
||||
uint32_t c_retrieved = read_u32(test);
|
||||
uint64_t d_retrieved = read_u64(test);
|
||||
int8_t e_retrieved = read_s8(test);
|
||||
float f_retrieved = read_f16(test);
|
||||
|
||||
rtt_f16(1.f);
|
||||
rtt_f16(3.14159f);
|
||||
rtt_f16(0.6666666666f);
|
||||
rtt_f16(1.f / 3.f);
|
||||
rtt_f16(99999.9f);
|
||||
|
||||
tetsuo = read_string(test);
|
||||
|
||||
std::cout << tetsuo << std::endl;
|
||||
|
Reference in New Issue
Block a user