Revision 92782e4a
Added by David Sorber over 4 years ago
| software/fixed/fixed_test.cc | ||
|---|---|---|
|
|
||
|
#include <cstdint>
|
||
|
#include <limits>
|
||
|
#include <random>
|
||
|
#include <sstream>
|
||
|
#include <string>
|
||
|
#include <vector>
|
||
|
|
||
|
#define BOOST_TEST_MAIN 1
|
||
|
#include <boost/test/unit_test.hpp>
|
||
| ... | ... | |
|
|
||
|
BOOST_AUTO_TEST_CASE(t0)
|
||
|
{
|
||
|
// Check overall type sizes
|
||
|
/* TEST CASE 0: Check storage sizes (in bytes) of all predefined fixed
|
||
|
* point types.
|
||
|
*/
|
||
|
fixed_8_8 f_8_8;
|
||
|
fixed_8_32 f_8_32;
|
||
|
fixed_8_16 f_8_16;
|
||
| ... | ... | |
|
BOOST_CHECK(sizeof(f_64_32) == 16);
|
||
|
BOOST_CHECK(sizeof(f_64_64) == 16);
|
||
|
}
|
||
|
|
||
|
BOOST_AUTO_TEST_CASE(t1)
|
||
|
{
|
||
|
/* TEST CASE 1: Test basic comparisons
|
||
|
*/
|
||
|
fixed_64_64 val1(100, 1, 0);
|
||
|
fixed_64_64 val2(100, 1);
|
||
|
|
||
|
BOOST_CHECK( (val1 == val2));
|
||
|
BOOST_CHECK(! (val1 != val2));
|
||
|
BOOST_CHECK(! (val1 > val2));
|
||
|
BOOST_CHECK(! (val1 < val2));
|
||
|
BOOST_CHECK( (val1 >= val2));
|
||
|
BOOST_CHECK( (val1 <= val2));
|
||
|
|
||
|
val2.assignUnscaledFrac(100, 1, 18);
|
||
|
|
||
|
BOOST_CHECK(! (val1 == val2));
|
||
|
BOOST_CHECK( (val1 != val2));
|
||
|
BOOST_CHECK( (val1 > val2));
|
||
|
BOOST_CHECK(! (val1 < val2));
|
||
|
BOOST_CHECK( (val1 >= val2));
|
||
|
BOOST_CHECK(! (val1 <= val2));
|
||
|
}
|
||
|
|
||
|
BOOST_AUTO_TEST_CASE(t2)
|
||
|
{
|
||
|
/* TEST CASE 2: Test parsing with leading zeros.
|
||
|
*/
|
||
|
fixed_64_64 val1;
|
||
|
fixed_64_64 val2;
|
||
|
|
||
|
// 1
|
||
|
val1.assign(1, 2000000000000000000);
|
||
|
val2.parse("1.2");
|
||
|
BOOST_CHECK(val1 == val2);
|
||
|
|
||
|
// 2
|
||
|
val1.assign(1, 200000000000000000);
|
||
|
val2.parse("1.02");
|
||
|
BOOST_CHECK(val1 == val2);
|
||
|
|
||
|
// 3
|
||
|
val1.assign(1, 20000000000000000);
|
||
|
val2.parse("1.002");
|
||
|
BOOST_CHECK(val1 == val2);
|
||
|
|
||
|
// 4
|
||
|
val1.assign(1, 2000000000000000);
|
||
|
val2.parse("1.0002");
|
||
|
BOOST_CHECK(val1 == val2);
|
||
|
|
||
|
// 5
|
||
|
val1.assign(1, 200000000000000);
|
||
|
val2.parse("1.00002");
|
||
|
BOOST_CHECK(val1 == val2);
|
||
|
|
||
|
// 6
|
||
|
val1.assign(1, 20000000000000);
|
||
|
val2.parse("1.000002");
|
||
|
BOOST_CHECK(val1 == val2);
|
||
|
|
||
|
// 7
|
||
|
val1.assign(1, 2000000000000);
|
||
|
val2.parse("1.0000002");
|
||
|
BOOST_CHECK(val1 == val2);
|
||
|
|
||
|
// 8
|
||
|
val1.assign(1, 200000000000);
|
||
|
val2.parse("1.00000002");
|
||
|
BOOST_CHECK(val1 == val2);
|
||
|
|
||
|
// 9
|
||
|
val1.assign(1, 20000000000);
|
||
|
val2.parse("1.000000002");
|
||
|
BOOST_CHECK(val1 == val2);
|
||
|
|
||
|
// 10
|
||
|
val1.assign(1, 2000000000);
|
||
|
val2.parse("1.0000000002");
|
||
|
BOOST_CHECK(val1 == val2);
|
||
|
|
||
|
// 11
|
||
|
val1.assign(1, 200000000);
|
||
|
val2.parse("1.00000000002");
|
||
|
BOOST_CHECK(val1 == val2);
|
||
|
|
||
|
// 12
|
||
|
val1.assign(1, 20000000);
|
||
|
val2.parse("1.000000000002");
|
||
|
BOOST_CHECK(val1 == val2);
|
||
|
|
||
|
// 13
|
||
|
val1.assign(1, 2000000);
|
||
|
val2.parse("1.0000000000002");
|
||
|
BOOST_CHECK(val1 == val2);
|
||
|
|
||
|
// 14
|
||
|
val1.assign(1, 200000);
|
||
|
val2.parse("1.00000000000002");
|
||
|
BOOST_CHECK(val1 == val2);
|
||
|
|
||
|
// 15
|
||
|
val1.assign(1, 20000);
|
||
|
val2.parse("1.000000000000002");
|
||
|
BOOST_CHECK(val1 == val2);
|
||
|
|
||
|
// 16
|
||
|
val1.assign(1, 2000);
|
||
|
val2.parse("1.0000000000000002");
|
||
|
BOOST_CHECK(val1 == val2);
|
||
|
|
||
|
// 17
|
||
|
val1.assign(1, 200);
|
||
|
val2.parse("1.00000000000000002");
|
||
|
BOOST_CHECK(val1 == val2);
|
||
|
|
||
|
// 18
|
||
|
val1.assign(1, 20);
|
||
|
val2.parse("1.000000000000000002");
|
||
|
BOOST_CHECK(val1 == val2);
|
||
|
|
||
|
// 19
|
||
|
val1.assign(1, 2);
|
||
|
val2.parse("1.0000000000000000002");
|
||
|
BOOST_CHECK(val1 == val2);
|
||
|
}
|
||
|
|
||
|
BOOST_AUTO_TEST_CASE(t3)
|
||
|
{
|
||
|
/* TEST CASE 3: Test parsing and printing randomly generated values
|
||
|
*/
|
||
|
using theType = fixed_64_64;
|
||
|
|
||
|
uint32_t NUMBER = 1000000;
|
||
|
uint64_t SEED = 0xDEADBEEF123;
|
||
|
|
||
|
std::random_device dev;
|
||
|
std::mt19937 rng;
|
||
|
rng.seed(SEED);
|
||
|
|
||
|
std::uniform_int_distribution<std::mt19937::result_type> intDigits(1, theType::integer_decimal_digits);
|
||
|
std::uniform_int_distribution<std::mt19937::result_type> fracDigits(1, theType::fractional_decimal_digits);
|
||
|
std::uniform_int_distribution<std::mt19937::result_type> digits(0, 9);
|
||
|
|
||
|
// Generate NUMBER worth of parsable decimal number strings
|
||
|
std::vector<std::string> values;
|
||
|
for (uint32_t idx = 0; idx < NUMBER; ++idx)
|
||
|
{
|
||
|
std::ostringstream output;
|
||
|
// Generate random integer number digits
|
||
|
for (uint32_t integerIdx = 0; integerIdx < intDigits(rng); ++integerIdx)
|
||
|
{
|
||
|
int digit = digits(rng);
|
||
|
|
||
|
// Integer part cannot start with a zero
|
||
|
if (integerIdx == 0)
|
||
|
{
|
||
|
while (digit == 0)
|
||
|
{
|
||
|
digit = digits(rng);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
output << digit;
|
||
|
}
|
||
|
|
||
|
output << ".";
|
||
|
|
||
|
// Generate random fractional number digits
|
||
|
int numFracDigits = fracDigits(rng);
|
||
|
for (uint32_t fracIdx = 0; fracIdx < numFracDigits; ++fracIdx)
|
||
|
{
|
||
|
int digit = digits(rng);
|
||
|
|
||
|
// Fractional part cannot end with a zero
|
||
|
if (fracIdx == (numFracDigits - 1))
|
||
|
{
|
||
|
while (digit == 0)
|
||
|
{
|
||
|
digit = digits(rng);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
output << digit;
|
||
|
}
|
||
|
|
||
|
values.emplace_back(output.str());
|
||
|
//~ std::cout << "VAL: " << values.back() << std::endl;
|
||
|
}
|
||
|
|
||
|
// Now validate that the output of the parsed
|
||
|
theType fixedValue;
|
||
|
std::ostringstream output;
|
||
|
for (auto& value : values)
|
||
|
{
|
||
|
fixedValue.parse(value.c_str());
|
||
|
output << fixedValue;
|
||
|
|
||
|
//~ std::cout << "TEST: " << output.str() << " -- " << value << std::endl;
|
||
|
BOOST_CHECK(output.str() == value);
|
||
|
output.str("");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
BOOST_AUTO_TEST_CASE(t4)
|
||
|
{
|
||
|
/* TEST CASE 4: Basic test division by unsigned integer
|
||
|
*/
|
||
|
fixed_64_64 val1(18, 55, 0);
|
||
|
fixed_64_64 val2(0, 1855, 0);
|
||
|
|
||
|
fixed_64_64 answer = val1 / 100;
|
||
|
BOOST_CHECK(answer == val2);
|
||
|
}
|
||
|
|
||
|
|
||
Additional improvements to the fixed type. Also added a few good test
cases.