#include "math/dvc_fix_point.h" #include "dvt_unit_common.h" #define _USE_MATH_DEFINES #include #include 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 (ret1iFloat32::kMax_float) { continue; } c = rand() & 0xFFF; ret2 = a * c; if (ret2iFloat32::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(0.25f); EXPECT_EQ(a, iFloat64::kQuater); EXPECT_EQ(a.s3132, iFloat64::kQuater.s3132); EXPECT_EQ(a.to_float(), 0.25f); EXPECT_EQ(a.to_int32(), 0); a = iFloat64(-0.25f); EXPECT_EQ(a, -iFloat64::kQuater); EXPECT_EQ(a.s3132, -iFloat64::kQuater.s3132); EXPECT_EQ(a.to_float(), -0.25f); EXPECT_EQ(a.to_int32(), -1); a = iFloat64(0.125f); EXPECT_EQ(a, iFloat64::kOneEighth); EXPECT_EQ(a.s3132, iFloat64::kOneEighth.s3132); EXPECT_EQ(a.to_float(), 0.125f); EXPECT_EQ(a.to_int32(), 0); a = iFloat64(-0.125f); EXPECT_EQ(a, -iFloat64::kOneEighth); EXPECT_EQ(a.s3132, -iFloat64::kOneEighth.s3132); EXPECT_EQ(a.to_float(), -0.125f); 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(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); } }