449 lines
11 KiB
C++
449 lines
11 KiB
C++
#include "math/dvc_fix_point.h"
|
|
#include "dvt_unit_common.h"
|
|
|
|
#define _USE_MATH_DEFINES
|
|
#include <cmath>
|
|
#include <gtest/gtest.h>
|
|
|
|
using namespace davinci;
|
|
|
|
TEST(FixPoint32, Basic)
|
|
{
|
|
iFloat32 a;
|
|
EXPECT_EQ(a.s1516, 0);
|
|
|
|
a = iFloat32(0);
|
|
EXPECT_EQ(a.s1516, iFloat32::kZero_s1516);
|
|
EXPECT_EQ(a.to_float(), 0.f);
|
|
EXPECT_EQ(a.to_int32(), 0);
|
|
|
|
a = iFloat32(0.5f);
|
|
EXPECT_EQ(a.s1516, iFloat32::kHalf_s1516);
|
|
EXPECT_EQ(a.to_float(), 0.5f);
|
|
EXPECT_EQ(a.to_int32(), 0);
|
|
|
|
a = iFloat32(1.0f);
|
|
EXPECT_EQ(a.s1516, iFloat32::kOne_s1516);
|
|
EXPECT_EQ(a.to_float(), 1.f);
|
|
EXPECT_EQ(a.to_int32(), 1);
|
|
|
|
a = iFloat32(-0.5f);
|
|
EXPECT_EQ(a.s1516, -iFloat32::kHalf_s1516);
|
|
EXPECT_EQ(a.to_float(), -0.5f);
|
|
EXPECT_EQ(a.to_int32(), -1);
|
|
|
|
a = iFloat32(-1.f);
|
|
EXPECT_EQ(a.s1516, iFloat32::kNegOne_s1516);
|
|
EXPECT_EQ(a.to_float(), -1.f);
|
|
EXPECT_EQ(a.to_int32(), -1);
|
|
|
|
a = iFloat32(1);
|
|
EXPECT_EQ(a.s1516, iFloat32::kOne_s1516);
|
|
EXPECT_EQ(a.to_float(), 1.f);
|
|
EXPECT_EQ(a.to_int32(), 1);
|
|
|
|
a = iFloat32(-1);
|
|
EXPECT_EQ(a.s1516, iFloat32::kNegOne_s1516);
|
|
EXPECT_EQ(a.to_float(), -1.f);
|
|
EXPECT_EQ(a.to_int32(), -1);
|
|
|
|
a = iFloat32(M_PI); //3.14
|
|
EXPECT_EQ(a.s1516, (int32_t)(M_PI * iFloat32::kFloatScale));
|
|
EXPECT_EQ(a.to_float(), ((int32_t)(M_PI * iFloat32::kFloatScale)) / (iFloat32::kFloatScale));
|
|
EXPECT_EQ(a.to_int32(), 3);
|
|
|
|
a = iFloat32(-M_PI); //-3.14
|
|
EXPECT_EQ(a.s1516, -(int32_t)(M_PI * iFloat32::kFloatScale));
|
|
EXPECT_EQ(a.to_float(), -((int32_t)(M_PI * iFloat32::kFloatScale)) / (iFloat32::kFloatScale));
|
|
EXPECT_EQ(a.to_int32(), -4);
|
|
|
|
a = iFloat32(-M_E); //-2.718
|
|
EXPECT_EQ(a.s1516, -(int32_t)(M_E * iFloat32::kFloatScale));
|
|
EXPECT_EQ(a.to_float(), -((int32_t)(M_E * iFloat32::kFloatScale)) / (iFloat32::kFloatScale));
|
|
EXPECT_EQ(a.to_int32(), -3);
|
|
}
|
|
|
|
TEST(FixPoint32, Range)
|
|
{
|
|
iFloat32 a;
|
|
|
|
a = iFloat32(iFloat32::kMax_float);
|
|
EXPECT_EQ(a.s1516, iFloat32::kMax_s1516);
|
|
EXPECT_EQ(a.to_float(), iFloat32::kMax_float);
|
|
EXPECT_EQ(a.to_int32(), iFloat32::kMax_int32);
|
|
|
|
a = iFloat32(iFloat32::kMax_float + 0.1f);
|
|
EXPECT_LT(a.s1516, 0);
|
|
EXPECT_LT(a.to_float(), 0);
|
|
EXPECT_LT(a.to_int32(), 0);
|
|
|
|
//a = iFloat32(iFloat32::kMax_int32);
|
|
//EXPECT_LT(a.s1516, iFloat32::kMax_s1516);
|
|
//EXPECT_LT(a.to_float(), iFloat32::kMax_float);
|
|
//EXPECT_EQ(a.to_int32(), iFloat32::kMax_int32);
|
|
|
|
a = iFloat32(iFloat32::kMax_int32 + 1);
|
|
EXPECT_LT(a.s1516, 0);
|
|
EXPECT_LT(a.to_float(), 0);
|
|
EXPECT_LT(a.to_int32(), 0);
|
|
|
|
a = iFloat32(iFloat32::kMin_float);
|
|
EXPECT_EQ(a.s1516, iFloat32::kMin_s1516);
|
|
EXPECT_EQ(a.to_float(), iFloat32::kMin_float);
|
|
EXPECT_EQ(a.to_int32(), iFloat32::kMin_int32);
|
|
|
|
a = iFloat32(iFloat32::kMin_float-1.f);
|
|
EXPECT_EQ(a.s1516, iFloat32::kMin_s1516);
|
|
EXPECT_EQ(a.to_float(), iFloat32::kMin_float);
|
|
EXPECT_EQ(a.to_int32(), iFloat32::kMin_int32);
|
|
|
|
a = iFloat32(iFloat32::kMin_int32);
|
|
EXPECT_EQ(a.s1516, iFloat32::kMin_s1516);
|
|
EXPECT_EQ(a.to_float(), iFloat32::kMin_float);
|
|
EXPECT_EQ(a.to_int32(), iFloat32::kMin_int32);
|
|
|
|
a = iFloat32(iFloat32::kMin_int32 - 1);
|
|
EXPECT_GT(a.s1516, 0);
|
|
EXPECT_GT(a.to_float(), 0);
|
|
EXPECT_GT(a.to_int32(), 0);
|
|
}
|
|
|
|
TEST(FixPoint32, Compare)
|
|
{
|
|
float a = _randomFloat();
|
|
iFloat32 ia = a;
|
|
EXPECT_EQ(ia.to_float(), a);
|
|
|
|
int32_t n = MathUtil::rangeRandom(iFloat32::kMin_int32, iFloat32::kMax_int32);
|
|
iFloat32 in = n;
|
|
EXPECT_EQ(in.to_int32(), n);
|
|
|
|
float f1 = _randomFloat(), f2 = f1 + 1.f;
|
|
iFloat32 iF1 = f1, iF2 = f2;
|
|
|
|
EXPECT_LT(iF1, iF2);
|
|
EXPECT_GT(iF2, iF1);
|
|
EXPECT_NE(iF1, iF2);
|
|
EXPECT_EQ(iF1, iF1);
|
|
|
|
iF1 += iF2;
|
|
EXPECT_EQ(iF1, f1 + f2);
|
|
|
|
iF1 -= iF2;
|
|
EXPECT_EQ(iF1, f1);
|
|
}
|
|
|
|
TEST(FixPoint32, Operation)
|
|
{
|
|
for (size_t i = 0; i < 500; i++)
|
|
{
|
|
float a = _randomFloat();
|
|
float b = _randomFloat();
|
|
|
|
iFloat32 ia(a), ib(b);
|
|
iFloat32 ret = ia + ib;
|
|
|
|
EXPECT_EQ(ret.to_float(), a + b);
|
|
|
|
iFloat32 ic(a);
|
|
iFloat32 ret2 = ic + b;
|
|
EXPECT_EQ(ret2.to_float(), a + b);
|
|
}
|
|
|
|
for (size_t i = 0; i < 500; i++)
|
|
{
|
|
float a = _randomFloat();
|
|
float b = _randomFloat();
|
|
|
|
iFloat32 ia(a), ib(b);
|
|
iFloat32 ret = ia - ib;
|
|
|
|
EXPECT_EQ(ret.to_float(), a - b);
|
|
|
|
iFloat32 ic(a);
|
|
iFloat32 ret2 = ic - b;
|
|
EXPECT_EQ(ret2.to_float(), a - b);
|
|
}
|
|
|
|
for (size_t i = 0; i < 500; i++)
|
|
{
|
|
float32_t a, b;
|
|
int32_t c;
|
|
float32_t ret1, ret2;
|
|
do {
|
|
a = _randomFloat();
|
|
b = _randomFloat();
|
|
|
|
ret1 = a * b;
|
|
if (ret1<iFloat32::kMin_float || ret1>iFloat32::kMax_float) {
|
|
continue;
|
|
}
|
|
|
|
c = rand() & 0xFFF;
|
|
ret2 = a * c;
|
|
if (ret2<iFloat32::kMin_float || ret2>iFloat32::kMax_float) {
|
|
continue;
|
|
}
|
|
break;
|
|
} while (true);
|
|
|
|
iFloat32 ia(a), ib(b);
|
|
iFloat32 iret1 = ia * ib;
|
|
EXPECT_LE(std::abs(iret1.to_float() - ret1), 0.01f);
|
|
|
|
iFloat32 iret2 = ia * b;
|
|
EXPECT_EQ(iret2, iret1);
|
|
|
|
iFloat32 iret3 = ia * c;
|
|
EXPECT_EQ(iret3.to_float(), ret2);
|
|
}
|
|
|
|
for (size_t i = 0; i < 500; i++)
|
|
{
|
|
float a, b, ret;
|
|
a = _randomFloat();
|
|
b = _randomFloat();
|
|
ret = a / b;
|
|
|
|
if (ret < iFloat32::kMin_float) ret = iFloat32::kMin_float;
|
|
else if (ret > iFloat32::kMax_float) ret = iFloat32::kMax_float;
|
|
|
|
iFloat32 ia(a), ib(b);
|
|
iFloat32 iret = ia / ib;
|
|
|
|
EXPECT_LE(std::abs(iret.to_float() - ret), 0.001f);
|
|
}
|
|
}
|
|
|
|
TEST(FixPoint64, Basic)
|
|
{
|
|
iFloat64 a;
|
|
EXPECT_EQ(a.s3132, 0);
|
|
|
|
a = iFloat64(0);
|
|
EXPECT_EQ(a.s3132, iFloat64::kZero.s3132);
|
|
EXPECT_EQ(a.to_float(), 0.f);
|
|
EXPECT_EQ(a.to_int32(), 0);
|
|
|
|
a = iFloat64(0.5f);
|
|
EXPECT_EQ(a, iFloat64::kHalf);
|
|
EXPECT_EQ(a.s3132, iFloat64::kHalf.s3132);
|
|
EXPECT_EQ(a.to_float(), 0.5f);
|
|
EXPECT_EQ(a.to_int32(), 0);
|
|
|
|
a = iFloat64(1.0f);
|
|
EXPECT_EQ(a, iFloat64::kOne);
|
|
EXPECT_EQ(a.s3132, iFloat64::kOne.s3132);
|
|
EXPECT_EQ(a.to_float(), 1.f);
|
|
EXPECT_EQ(a.to_int32(), 1);
|
|
|
|
a = iFloat64(-0.5f);
|
|
EXPECT_EQ(a, -iFloat64::kHalf);
|
|
EXPECT_EQ(a.s3132, -iFloat64::kHalf.s3132);
|
|
EXPECT_EQ(a.to_float(), -0.5f);
|
|
EXPECT_EQ(a.to_int32(), -1);
|
|
|
|
a = iFloat64(-1.f);
|
|
EXPECT_EQ(a, -iFloat64::kOne);
|
|
EXPECT_EQ(a.s3132, iFloat64::kNegOne.s3132);
|
|
EXPECT_EQ(a.to_float(), -1.f);
|
|
EXPECT_EQ(a.to_int32(), -1);
|
|
|
|
a = iFloat64(1);
|
|
EXPECT_EQ(a, iFloat64::kOne);
|
|
EXPECT_EQ(a.s3132, iFloat64::kOne.s3132);
|
|
EXPECT_EQ(a.to_float(), 1.f);
|
|
EXPECT_EQ(a.to_int32(), 1);
|
|
|
|
a = iFloat64(-1);
|
|
EXPECT_EQ(a, -iFloat64::kOne);
|
|
EXPECT_EQ(a.s3132, iFloat64::kNegOne.s3132);
|
|
EXPECT_EQ(a.to_float(), -1.f);
|
|
EXPECT_EQ(a.to_int32(), -1);
|
|
|
|
a = iFloat64(M_PI); //3.14
|
|
EXPECT_EQ(a, iFloat64::kPi);
|
|
EXPECT_EQ(a.s3132, iFloat64::kPi.s3132);
|
|
EXPECT_EQ(a.to_float(), (float32_t)((int64_t)(M_PI * iFloat64::kFloatScale)) / (iFloat64::kFloatScale));
|
|
EXPECT_EQ(a.to_int32(), 3);
|
|
|
|
a = iFloat64(M_PI*2); //2*3.14
|
|
EXPECT_EQ(a, iFloat64::kPi2);
|
|
EXPECT_EQ(a.s3132, iFloat64::kPi2.s3132);
|
|
EXPECT_EQ(a.to_float(), (float32_t)((int64_t)(2 * M_PI * iFloat64::kFloatScale)) / (iFloat64::kFloatScale));
|
|
EXPECT_EQ(a.to_int32(), 6);
|
|
|
|
a = iFloat64(M_PI * 0.5); //0.5*3.14
|
|
EXPECT_EQ(a, iFloat64::kPiHalf);
|
|
EXPECT_EQ(a.s3132, iFloat64::kPiHalf.s3132);
|
|
EXPECT_EQ(a.to_float(), (float32_t)((int64_t)(0.5 * M_PI * iFloat64::kFloatScale)) / (iFloat64::kFloatScale));
|
|
EXPECT_EQ(a.to_int32(), 1);
|
|
|
|
a = iFloat64(-M_PI); //-3.14
|
|
EXPECT_EQ(a, -iFloat64::kPi);
|
|
EXPECT_EQ(a.s3132, -iFloat64::kPi.s3132);
|
|
EXPECT_EQ(a.to_float(), -(float32_t)((int64_t)(M_PI * iFloat64::kFloatScale)) / (iFloat64::kFloatScale));
|
|
EXPECT_EQ(a.to_int32(), -4);
|
|
|
|
a = iFloat64(M_E); //2.718
|
|
EXPECT_EQ(a, iFloat64::kE);
|
|
EXPECT_EQ(a.s3132, iFloat64::kE.s3132);
|
|
EXPECT_EQ(a.to_float(), (float32_t)((int64_t)(M_E * iFloat64::kFloatScale)) / (iFloat64::kFloatScale));
|
|
EXPECT_EQ(a.to_int32(), 2);
|
|
|
|
a = iFloat64(-M_E); //-2.718
|
|
EXPECT_EQ(a, -iFloat64::kE);
|
|
EXPECT_EQ(a.s3132, -iFloat64::kE.s3132);
|
|
EXPECT_EQ(a.to_float(), -(float32_t)((int64_t)(M_E * iFloat64::kFloatScale)) / (iFloat64::kFloatScale));
|
|
EXPECT_EQ(a.to_int32(), -3);
|
|
}
|
|
|
|
TEST(FixPoint64, Range)
|
|
{
|
|
iFloat64 a;
|
|
|
|
static constexpr int32_t kShift = 32;
|
|
static constexpr float64_t kFloatScale = static_cast<float64_t>(1LL << kShift); //4294967296.0
|
|
static constexpr float64_t kFloatInvScale = 1.0 / kFloatScale;
|
|
|
|
a = iFloat64(iFloat64::kMax_float);
|
|
EXPECT_LE(a.s3132, iFloat64::kMax_s3132);
|
|
EXPECT_LE(a.to_float(), iFloat64::kMax_float);
|
|
EXPECT_LE(a.to_int32(), iFloat64::kMax_int32);
|
|
|
|
a = iFloat64(nextafter(iFloat64::kMax_float, FLT_MAX));
|
|
EXPECT_LT(a.s3132, 0);
|
|
EXPECT_LT(a.to_float(), 0.f);
|
|
EXPECT_LT(a.to_int32(), 0);
|
|
|
|
a = iFloat64(iFloat64::kMax_int32);
|
|
EXPECT_LE(a.s3132, iFloat64::kMax_s3132);
|
|
EXPECT_LE(a.to_int32(), iFloat64::kMax_int32);
|
|
|
|
a = iFloat64(iFloat64::kMax_int32+1);
|
|
EXPECT_LT(a.s3132, 0);
|
|
EXPECT_LT(a.to_float(), 0.f);
|
|
EXPECT_LT(a.to_int32(), 0);
|
|
|
|
a = iFloat64(iFloat64::kMin_float);
|
|
EXPECT_EQ(a.s3132, iFloat64::kMin_s3132);
|
|
EXPECT_EQ(a.to_float(), iFloat64::kMin_float);
|
|
EXPECT_EQ(a.to_int32(), iFloat64::kMin_int32);
|
|
|
|
a = iFloat64(iFloat64::kMin_float - 1.f);
|
|
EXPECT_EQ(a.s3132, iFloat64::kMin_s3132);
|
|
EXPECT_EQ(a.to_float(), iFloat64::kMin_float);
|
|
EXPECT_EQ(a.to_int32(), iFloat64::kMin_int32);
|
|
|
|
a = iFloat64(iFloat64::kMin_int32);
|
|
EXPECT_EQ(a.s3132, iFloat64::kMin_s3132);
|
|
EXPECT_EQ(a.to_float(), iFloat64::kMin_float);
|
|
EXPECT_EQ(a.to_int32(), iFloat64::kMin_int32);
|
|
|
|
a = iFloat64(iFloat64::kMin_int32 - 1);
|
|
EXPECT_GT(a.s3132, 0);
|
|
EXPECT_GT(a.to_float(), 0);
|
|
EXPECT_GT(a.to_int32(), 0);
|
|
|
|
a = iFloat64(iFloat64::kMax_float - 100.f) + iFloat64(iFloat64::kMax_float - 200.f);
|
|
EXPECT_LT(a.s3132, 0);
|
|
EXPECT_LT(a.to_float(), 0.f);
|
|
EXPECT_LT(a.to_int32(), 0);
|
|
|
|
a = iFloat64(iFloat64::kMin_float + 100.f) - iFloat64(iFloat64::kMax_float + 200.f);
|
|
EXPECT_GT(a.s3132, 0);
|
|
EXPECT_GT(a.to_float(), 0.f);
|
|
EXPECT_GT(a.to_int32(), 0);
|
|
}
|
|
|
|
TEST(FixPoint64, Compare)
|
|
{
|
|
float a = _randomFloat();
|
|
iFloat64 ia = a;
|
|
EXPECT_EQ(ia.to_float(), a);
|
|
|
|
int32_t n = MathUtil::rangeRandom(iFloat64::kMin_int32, iFloat64::kMax_int32);
|
|
iFloat64 in = n;
|
|
EXPECT_EQ(in.to_int32(), n);
|
|
|
|
float f1 = _randomFloat(), f2 = f1 + 1.f;
|
|
iFloat64 iF1 = f1, iF2 = f2;
|
|
|
|
EXPECT_LT(iF1, iF2); // <
|
|
EXPECT_GT(iF2, iF1); // >
|
|
EXPECT_NE(iF1, iF2); // !=
|
|
EXPECT_EQ(iF1, iF1); // ==
|
|
|
|
iF1 += iF2;
|
|
EXPECT_EQ(iF1, f1 + f2);
|
|
|
|
iF1 -= iF2;
|
|
EXPECT_EQ(iF1, f1);
|
|
}
|
|
|
|
TEST(FixPoint64, Operation)
|
|
{
|
|
for (size_t i = 0; i < 500; i++)
|
|
{
|
|
float a = _randomFloat();
|
|
float b = _randomFloat();
|
|
|
|
iFloat64 ia(a), ib(b);
|
|
iFloat64 ret = ia + ib;
|
|
|
|
EXPECT_EQ(ret.to_float(), a + b);
|
|
|
|
iFloat64 ic(a);
|
|
iFloat64 ret2 = ic + b;
|
|
EXPECT_EQ(ret2.to_float(), a + b);
|
|
}
|
|
|
|
for (size_t i = 0; i < 500; i++)
|
|
{
|
|
float a = _randomFloat();
|
|
float b = _randomFloat();
|
|
|
|
iFloat64 ia(a), ib(b);
|
|
iFloat64 ret = ia - ib;
|
|
|
|
EXPECT_EQ(ret.to_float(), a - b);
|
|
|
|
iFloat64 ic(a);
|
|
iFloat64 ret2 = ic - b;
|
|
EXPECT_EQ(ret2.to_float(), a - b);
|
|
}
|
|
|
|
for (size_t i = 0; i < 500; i++)
|
|
{
|
|
float32_t a = _randomFloat();
|
|
float32_t b = _randomFloat();
|
|
int32_t c = rand() & 0xFFFF;
|
|
|
|
// iFloat*iFloat
|
|
iFloat64 ia(a), ib(b);
|
|
iFloat64 iret = ia * ib;
|
|
EXPECT_EQ(iret.to_float(), a*b);
|
|
|
|
// iFloat*int
|
|
iFloat64 iret2 = ia * c;
|
|
EXPECT_EQ(iret2.to_float(), a * c);
|
|
|
|
// iFloat*float
|
|
iFloat64 iret3 = ia * b;
|
|
EXPECT_EQ(iret3, iret);
|
|
}
|
|
|
|
for (size_t i = 0; i < 500; i++)
|
|
{
|
|
float a, b, ret;
|
|
a = _randomFloat();
|
|
b = _randomFloat();
|
|
ret = a / b;
|
|
|
|
iFloat64 ia(a), ib(b);
|
|
iFloat64 iret = ia / ib;
|
|
|
|
EXPECT_LE(std::abs(iret.to_float() - ret), 0.001f);
|
|
}
|
|
}
|