OXYGENHUB
◆ main openmsx / src / unittest / Math_test.cc
4.0 KiB · C++ · last changed chore(): initial commit 1 month ago source blame history raw
e8555c89 Andy McCall 1
#include "catch.hpp"
2
#include "Math.hh"
3
4
TEST_CASE("Math::clipToInt16")
5
{
6
	CHECK(Math::clipToInt16(-100000) == -32768);
7
	CHECK(Math::clipToInt16( -32769) == -32768);
8
	CHECK(Math::clipToInt16( -32768) == -32768);
9
	CHECK(Math::clipToInt16( -32767) == -32767);
10
	CHECK(Math::clipToInt16( -10000) == -10000);
11
	CHECK(Math::clipToInt16(    -10) ==    -10);
12
	CHECK(Math::clipToInt16(     -1) ==     -1);
13
	CHECK(Math::clipToInt16(      0) ==      0);
14
	CHECK(Math::clipToInt16(      1) ==      1);
15
	CHECK(Math::clipToInt16(     10) ==     10);
16
	CHECK(Math::clipToInt16(   9876) ==   9876);
17
	CHECK(Math::clipToInt16(  32766) ==  32766);
18
	CHECK(Math::clipToInt16(  32767) ==  32767);
19
	CHECK(Math::clipToInt16(  32768) ==  32767);
20
	CHECK(Math::clipToInt16( 100000) ==  32767);
21
22
	CHECK(Math::clipToInt16(-10'000'000'000LL) == -32768);
23
	CHECK(Math::clipToInt16(             17LL) ==     17);
24
	CHECK(Math::clipToInt16( 10'000'000'000LL) ==  32767);
25
}
26
27
TEST_CASE("Math::clipIntToByte")
28
{
29
	CHECK(Math::clipIntToByte(-100) ==   0);
30
	CHECK(Math::clipIntToByte( -27) ==   0);
31
	CHECK(Math::clipIntToByte(  -1) ==   0);
32
	CHECK(Math::clipIntToByte(   0) ==   0);
33
	CHECK(Math::clipIntToByte(   1) ==   1);
34
	CHECK(Math::clipIntToByte(  10) ==  10);
35
	CHECK(Math::clipIntToByte( 127) == 127);
36
	CHECK(Math::clipIntToByte( 128) == 128);
37
	CHECK(Math::clipIntToByte( 222) == 222);
38
	CHECK(Math::clipIntToByte( 255) == 255);
39
	CHECK(Math::clipIntToByte( 256) == 255);
40
	CHECK(Math::clipIntToByte( 257) == 255);
41
	CHECK(Math::clipIntToByte( 327) == 255);
42
}
43
44
static void testReverseNBits(unsigned x, unsigned n, unsigned expected)
45
{
46
	CHECK(Math::reverseNBits(x, n) == expected);
47
	CHECK(Math::reverseNBits(expected, n) == x);
48
}
49
TEST_CASE("Math::reverseNBits")
50
{
51
	testReverseNBits(0x0, 4, 0x0);
52
	testReverseNBits(0x1, 4, 0x8);
53
	testReverseNBits(0x2, 4, 0x4);
54
	testReverseNBits(0x3, 4, 0xC);
55
	testReverseNBits(0x4, 4, 0x2);
56
	testReverseNBits(0x8, 4, 0x1);
57
	testReverseNBits(0x6, 4, 0x6);
58
	testReverseNBits(0xE, 4, 0x7);
59
	testReverseNBits(0xF, 4, 0xF);
60
	testReverseNBits(0x00012345, 22, 0x0028B120);
61
	testReverseNBits(0x0010000F, 32, 0xF0000800);
62
}
63
64
static void testReverseByte(uint8_t x, uint8_t expected)
65
{
66
	CHECK(Math::reverseByte (x   ) == expected);
67
	CHECK(Math::reverseNBits(x, 8) == expected);
68
69
	CHECK(Math::reverseByte (expected   ) == x);
70
	CHECK(Math::reverseNBits(expected, 8) == x);
71
}
72
TEST_CASE("Math::reverseByte")
73
{
74
	testReverseByte(0x00, 0x00);
75
	testReverseByte(0x01, 0x80);
76
	testReverseByte(0x02, 0x40);
77
	testReverseByte(0x07, 0xE0);
78
	testReverseByte(0x12, 0x48);
79
	testReverseByte(0x73, 0xCE);
80
	testReverseByte(0x7F, 0xFE);
81
	testReverseByte(0x8C, 0x31);
82
	testReverseByte(0xAB, 0xD5);
83
	testReverseByte(0xE4, 0x27);
84
	testReverseByte(0xF0, 0x0F);
85
}
86
87
TEST_CASE("Math::floodRight")
88
{
89
	CHECK(Math::floodRight(0u) == 0);
90
	CHECK(Math::floodRight(1u) == 1);
91
	CHECK(Math::floodRight(2u) == 3);
92
	CHECK(Math::floodRight(3u) == 3);
93
	CHECK(Math::floodRight(4u) == 7);
94
	CHECK(Math::floodRight(5u) == 7);
95
	CHECK(Math::floodRight(6u) == 7);
96
	CHECK(Math::floodRight(7u) == 7);
97
	CHECK(Math::floodRight(8u) == 15);
98
	CHECK(Math::floodRight(9u) == 15);
99
	CHECK(Math::floodRight(15u) == 15);
100
	CHECK(Math::floodRight(16u) == 31);
101
	CHECK(Math::floodRight(32u) == 63);
102
	CHECK(Math::floodRight(64u) == 127);
103
	CHECK(Math::floodRight(12345u) == 16383);
104
	CHECK(Math::floodRight(0x7F001234u) == 0x7FFFFFFF);
105
	CHECK(Math::floodRight(0x80000000u) == 0xFFFFFFFF);
106
	CHECK(Math::floodRight(0xF0FEDCBAu) == 0xFFFFFFFF);
107
	CHECK(Math::floodRight(0x1234F0FEDCBAULL) == 0x1FFFFFFFFFFFULL);
108
	CHECK(Math::floodRight(uint8_t(0x12)) == uint8_t(0x1F));
109
	CHECK(Math::floodRight(uint16_t(0x2512)) == uint16_t(0x3FFF));
110
}
111
112
TEST_CASE("Math::div_mod_floor")
113
{
114
	auto test = [](int D, int d, int q, int r) {
115
		REQUIRE(d * q + r == D);
116
		auto qr = Math::div_mod_floor(D, d);
117
		CHECK(qr.quotient  == q);
118
		CHECK(qr.remainder == r);
119
	};
120
	test( 10,  3,  3,  1);
121
	test(-10,  3, -4,  2);
122
	test( 10, -3, -4, -2);
123
	test(-10, -3,  3, -1);
124
125
	test( 10,  2,  5,  0);
126
	test(-10,  2, -5,  0);
127
	test( 10, -2, -5,  0);
128
	test(-10, -2,  5,  0);
129
}