mirror of
https://github.com/luanti-org/luanti.git
synced 2025-07-02 16:38:41 +00:00
Network: Send IEEE floats (#7768)
This commit is contained in:
parent
8471d027b9
commit
839e935ba0
9 changed files with 317 additions and 12 deletions
|
@ -21,6 +21,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
|
||||
#include "util/string.h"
|
||||
#include "util/serialize.h"
|
||||
#include <cmath>
|
||||
|
||||
class TestSerialization : public TestBase {
|
||||
public:
|
||||
|
@ -43,6 +44,7 @@ public:
|
|||
void testVecPut();
|
||||
void testStringLengthLimits();
|
||||
void testBufReader();
|
||||
void testFloatFormat();
|
||||
|
||||
std::string teststring2;
|
||||
std::wstring teststring2_w;
|
||||
|
@ -70,6 +72,7 @@ void TestSerialization::runTests(IGameDef *gamedef)
|
|||
TEST(testVecPut);
|
||||
TEST(testStringLengthLimits);
|
||||
TEST(testBufReader);
|
||||
TEST(testFloatFormat);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -631,6 +634,75 @@ void TestSerialization::testBufReader()
|
|||
UASSERT(!buf.getRawDataNoEx(raw_data, sizeof(raw_data)));
|
||||
}
|
||||
|
||||
void TestSerialization::testFloatFormat()
|
||||
{
|
||||
FloatType type = getFloatSerializationType();
|
||||
u32 i;
|
||||
f32 fs, fm;
|
||||
|
||||
// Check precision of float calculations on this platform
|
||||
const std::unordered_map<f32, u32> float_results = {
|
||||
{ 0.0f, 0x00000000UL },
|
||||
{ 1.0f, 0x3F800000UL },
|
||||
{ -1.0f, 0xBF800000UL },
|
||||
{ 0.1f, 0x3DCCCCCDUL },
|
||||
{ -0.1f, 0xBDCCCCCDUL },
|
||||
{ 1945329.25f, 0x49ED778AUL },
|
||||
{ -23298764.f, 0xCBB1C166UL },
|
||||
{ 0.5f, 0x3F000000UL },
|
||||
{ -0.5f, 0xBF000000UL }
|
||||
};
|
||||
for (const auto &v : float_results) {
|
||||
i = f32Tou32Slow(v.first);
|
||||
if (std::abs((s64)v.second - i) > 32) {
|
||||
printf("Inaccurate float values on %.9g, expected 0x%X, actual 0x%X\n",
|
||||
v.first, v.second, i);
|
||||
UASSERT(false);
|
||||
}
|
||||
|
||||
fs = u32Tof32Slow(v.second);
|
||||
if (std::fabs(v.first - fs) > std::fabs(v.first * 0.000005f)) {
|
||||
printf("Inaccurate float values on 0x%X, expected %.9g, actual 0x%.9g\n",
|
||||
v.second, v.first, fs);
|
||||
UASSERT(false);
|
||||
}
|
||||
}
|
||||
|
||||
if (type == FLOATTYPE_SLOW) {
|
||||
// conversion using memcpy is not possible
|
||||
// Skip exact float comparison checks below
|
||||
return;
|
||||
}
|
||||
|
||||
auto test_single = [&fs, &fm](const u32 &i) -> bool {
|
||||
memcpy(&fm, &i, 4);
|
||||
fs = u32Tof32Slow(i);
|
||||
if (fm != fs) {
|
||||
printf("u32Tof32Slow failed on 0x%X, expected %.9g, actual %.9g\n",
|
||||
i, fm, fs);
|
||||
return false;
|
||||
}
|
||||
if (f32Tou32Slow(fs) != i) {
|
||||
printf("f32Tou32Slow failed on %.9g, expected 0x%X, actual 0x%X\n",
|
||||
fs, i, f32Tou32Slow(fs));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
// Use step of prime 277 to speed things up from 3 minutes to a few seconds
|
||||
// Test from 0 to 0xFF800000UL (positive)
|
||||
for (i = 0x00000000UL; i <= 0x7F800000UL; i += 277)
|
||||
UASSERT(test_single(i));
|
||||
|
||||
// Ensure +inf and -inf are tested
|
||||
UASSERT(test_single(0x7F800000UL));
|
||||
UASSERT(test_single(0xFF800000UL));
|
||||
|
||||
// Test from 0x80000000UL to 0xFF800000UL (negative)
|
||||
for (i = 0x80000000UL; i <= 0xFF800000UL; i += 277)
|
||||
UASSERT(test_single(i));
|
||||
}
|
||||
|
||||
const u8 TestSerialization::test_serialized_data[12 * 13] = {
|
||||
0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue