123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413 |
- #include <library/cpp/testing/unittest/registar.h>
- #include <library/cpp/int128/int128.h>
- #include <util/generic/cast.h>
- Y_UNIT_TEST_SUITE(I128DivisionBy1Suite) {
- Y_UNIT_TEST(I128Divide0By1) {
- i128 dividend = 0;
- i128 divider = 1;
- i128 expectedQuotient = 0;
- i128 expectedRemainder = 0;
- UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
- UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
- }
- Y_UNIT_TEST(I128Divide1By1) {
- i128 dividend = 1;
- i128 divider = 1;
- i128 expectedQuotient = 1;
- i128 expectedRemainder = 0;
- UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
- UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
- }
- Y_UNIT_TEST(I128Divide2By1) {
- i128 dividend = 2;
- i128 divider = 1;
- i128 expectedQuotient = 2;
- i128 expectedRemainder = 0;
- UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
- UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
- }
- Y_UNIT_TEST(I128Divide42By1) {
- i128 dividend = 42;
- i128 divider = 1;
- i128 expectedQuotient = 42;
- i128 expectedRemainder = 0;
- UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
- UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
- }
- Y_UNIT_TEST(I128DivideMaxUi64By1) {
- i128 dividend = std::numeric_limits<ui64>::max();
- i128 divider = 1;
- i128 expectedQuotient = std::numeric_limits<ui64>::max();
- i128 expectedRemainder = 0;
- UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
- UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
- }
- Y_UNIT_TEST(I128DivideMaxUi64Plus1By1) {
- i128 dividend = i128{std::numeric_limits<ui64>::max()} + i128{1};
- i128 divider = 1;
- i128 expectedQuotient = i128{std::numeric_limits<ui64>::max()} + i128{1};
- i128 expectedRemainder = 0;
- UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
- UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
- }
- Y_UNIT_TEST(I128DivideMaxUi64Plus42By1) {
- i128 dividend = i128{std::numeric_limits<ui64>::max()} + i128{42};
- i128 divider = 1;
- i128 expectedQuotient = i128{std::numeric_limits<ui64>::max()} + i128{42};
- i128 expectedRemainder = 0;
- UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
- UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
- }
- Y_UNIT_TEST(I128DivideMaxI128By1) {
- i128 dividend = std::numeric_limits<i128>::max();
- i128 divider = 1;
- i128 expectedQuotient = std::numeric_limits<i128>::max();
- i128 expectedRemainder = 0;
- UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
- UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
- }
- Y_UNIT_TEST(I128DivideMaxI128Minus1By1) {
- i128 dividend = std::numeric_limits<i128>::max() - 1;
- i128 divider = 1;
- i128 expectedQuotient = std::numeric_limits<i128>::max() - 1;
- i128 expectedRemainder = 0;
- UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
- UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
- }
- }
- Y_UNIT_TEST_SUITE(I128DivisionByEqualSuite) {
- Y_UNIT_TEST(I128Divide1ByEqual) {
- i128 dividend = 1;
- i128 divider = dividend;
- i128 expectedQuotient = 1;
- i128 expectedRemainder = 0;
- UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
- UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
- }
- Y_UNIT_TEST(I128Divide2ByEqual) {
- i128 dividend = 2;
- i128 divider = dividend;
- i128 expectedQuotient = 1;
- i128 expectedRemainder = 0;
- UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
- UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
- }
- Y_UNIT_TEST(I128Divide42ByEqual) {
- i128 dividend = 42;
- i128 divider = dividend;
- i128 expectedQuotient = 1;
- i128 expectedRemainder = 0;
- UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
- UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
- }
- Y_UNIT_TEST(I128DivideMaxUi64ByEqual) {
- i128 dividend = std::numeric_limits<ui64>::max();
- i128 divider = dividend;
- i128 expectedQuotient = 1;
- i128 expectedRemainder = 0;
- UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
- UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
- }
- Y_UNIT_TEST(I128DivideMaxUi64Plus1ByEqual) {
- i128 dividend = i128{std::numeric_limits<ui64>::max()} + i128{1};
- i128 divider = dividend;
- i128 expectedQuotient = 1;
- i128 expectedRemainder = 0;
- UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
- UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
- }
- Y_UNIT_TEST(I128DivideMaxUi64Plus42ByEqual) {
- i128 dividend = i128{std::numeric_limits<ui64>::max()} + i128{42};
- i128 divider = dividend;
- i128 expectedQuotient = 1;
- i128 expectedRemainder = 0;
- UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
- UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
- }
- Y_UNIT_TEST(I128DivideMaxI128ByEqual) {
- i128 dividend = std::numeric_limits<i128>::max();
- i128 divider = dividend;
- i128 expectedQuotient = 1;
- i128 expectedRemainder = 0;
- UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
- UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
- }
- Y_UNIT_TEST(I128DivideMaxI128Minus1ByEqual) {
- i128 dividend = std::numeric_limits<i128>::max() - 1;
- i128 divider = dividend;
- i128 expectedQuotient = 1;
- i128 expectedRemainder = 0;
- UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
- UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
- }
- }
- Y_UNIT_TEST_SUITE(I128DivisionLessByHigherSuite) {
- Y_UNIT_TEST(I128Divide42By84) {
- i128 dividend = 42;
- i128 divider = 84;
- i128 expectedQuotient = 0;
- i128 expectedRemainder = 42;
- UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
- UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
- }
- Y_UNIT_TEST(I128Divide42ByMaxUi64) {
- i128 dividend = 42;
- i128 divider = std::numeric_limits<ui64>::max();
- i128 expectedQuotient = 0;
- i128 expectedRemainder = 42;
- UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
- UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
- }
- Y_UNIT_TEST(I128Divide42ByMaxUi64Plus1) {
- i128 dividend = 42;
- i128 divider = i128{std::numeric_limits<ui64>::max()} + i128{1};
- i128 expectedQuotient = 0;
- i128 expectedRemainder = 42;
- UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
- UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
- }
- Y_UNIT_TEST(I128DivideMaxUi64ByMaxUi64Plus1) {
- i128 dividend = i128{std::numeric_limits<ui64>::max()};
- i128 divider = i128{std::numeric_limits<ui64>::max()} + i128{1};
- i128 expectedQuotient = 0;
- i128 expectedRemainder = i128{std::numeric_limits<ui64>::max()};
- UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
- UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
- }
- }
- Y_UNIT_TEST_SUITE(I128DivisionWithDifferentSigns) {
- Y_UNIT_TEST(DivisionPositiveByNegative) {
- i128 dividend = i128{100};
- i128 divider = i128{-33};
- i128 expectedQuotient = -3;
- i128 expectedRemainder = 1;
- i128 quotient = dividend / divider;
- i128 remainder = dividend % divider;
- UNIT_ASSERT_EQUAL(quotient, expectedQuotient);
- UNIT_ASSERT_EQUAL(remainder, expectedRemainder);
- }
- Y_UNIT_TEST(DivisionNegativeByPositive) {
- i128 dividend = i128{-100};
- i128 divider = i128{33};
- i128 expectedQuotient = -3;
- i128 expectedRemainder = -1;
- i128 quotient = dividend / divider;
- i128 remainder = dividend % divider;
- UNIT_ASSERT_EQUAL(quotient, expectedQuotient);
- UNIT_ASSERT_EQUAL(remainder, expectedRemainder);
- }
- Y_UNIT_TEST(DivisionNegativeByNegative) {
- i128 dividend = i128{-100};
- i128 divider = i128{-33};
- i128 expectedQuotient = 3;
- i128 expectedRemainder = -1;
- i128 quotient = dividend / divider;
- i128 remainder = dividend % divider;
- UNIT_ASSERT_EQUAL(quotient, expectedQuotient);
- UNIT_ASSERT_EQUAL(remainder, expectedRemainder);
- }
- }
- Y_UNIT_TEST_SUITE(i128DivisionBigByBigSuite) {
- Y_UNIT_TEST(i128DivideBigByBig1) {
- i128 dividend = {64, 0};
- i128 divider = {1, 0};
- i128 expectedQuotient = 64;
- i128 expectedRemainder = 0;
- UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
- UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
- }
- Y_UNIT_TEST(i128DivideBigByBig1_PosByNeg) {
- i128 dividend = i128{64, 0};
- i128 divider = -i128{1, 0};
- i128 expectedQuotient = -i128{64};
- i128 expectedRemainder = 0;
- UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
- UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
- }
- Y_UNIT_TEST(i128DivideBigByBig1_NegByPos) {
- i128 dividend = -i128{64, 0};
- i128 divider = i128{1, 0};
- i128 expectedQuotient = -i128{64};
- i128 expectedRemainder = 0;
- UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
- UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
- }
- Y_UNIT_TEST(i128DivideBigByBig1_NegByNeg) {
- i128 dividend = -i128{64, 0};
- i128 divider = -i128{1, 0};
- i128 expectedQuotient = i128{64};
- i128 expectedRemainder = 0;
- UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
- UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
- }
- Y_UNIT_TEST(i128DivideBigByBig2) {
- i128 dividend = {64, 0};
- i128 divider = {12, 5};
- i128 expectedQuotient = 5;
- i128 expectedRemainder = i128{3, 18446744073709551591ull}; // plz don't ask
- UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
- UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
- }
- Y_UNIT_TEST(i128DivideBigByBig2_PosByNeg) {
- i128 dividend = i128{64, 0};
- i128 divider = -i128{12, 5};
- i128 expectedQuotient = -5;
- i128 expectedRemainder = i128{3, 18446744073709551591ull};
- UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
- UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
- }
- Y_UNIT_TEST(i128DivideBigByBig2_NegByPos) {
- i128 dividend = -i128{64, 0};
- i128 divider = i128{12, 5};
- i128 expectedQuotient = -5;
- i128 expectedRemainder = -i128{3, 18446744073709551591ull};
- UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
- UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
- }
- Y_UNIT_TEST(i128DivideBigByBig2_NegByNeg) {
- i128 dividend = -i128{64, 0};
- i128 divider = -i128{12, 5};
- i128 expectedQuotient = 5;
- i128 expectedRemainder = -i128{3, 18446744073709551591ull};
- UNIT_ASSERT_EQUAL(dividend / divider, expectedQuotient);
- UNIT_ASSERT_EQUAL(dividend % divider, expectedRemainder);
- }
- }
- Y_UNIT_TEST_SUITE(i128DivisionAlgo) {
- Y_UNIT_TEST(ii128DivideAlgoCheck_PosByPos) {
- /*
- 49672666804009505000000 / 10000000 == 4967266680400950
- 49672666804009505000000 % 10000000 == 5000000
- */
- i128 dividend = {2692ull, 14031757583392049728ull};
- i64 divider = 10000000;
- i128 expectedQuotient = {0, 4967266680400950ull};
- i128 expectedRemainder = {0, 5000000ull};
- i128 quotient = dividend / divider;
- i128 reminder = dividend % divider;
- UNIT_ASSERT_EQUAL(quotient, expectedQuotient);
- UNIT_ASSERT_EQUAL(reminder, expectedRemainder);
- }
- Y_UNIT_TEST(ii128DivideAlgoCheck_PosByNeg) {
- /*
- 49672666804009505000000 / -10000000 == -4967266680400950
- 49672666804009505000000 % -10000000 == 5000000
- */
- i128 dividend = {2692ull, 14031757583392049728ull};
- i64 divider = -10000000;
- i128 expectedQuotient = -i128{0, 4967266680400950ull};
- i128 expectedRemainder = {0, 5000000ull};
- i128 quotient = dividend / divider;
- i128 reminder = dividend % divider;
- UNIT_ASSERT_EQUAL(quotient, expectedQuotient);
- UNIT_ASSERT_EQUAL(reminder, expectedRemainder);
- }
- Y_UNIT_TEST(ii128DivideAlgoCheck_NegByPos) {
- /*
- -49672666804009505000000 / 10000000 == -4967266680400950
- -49672666804009505000000 % 10000000 == -5000000
- */
- i128 dividend = -i128{2692ull, 14031757583392049728ull};
- i64 divider = 10000000;
- i128 expectedQuotient = -i128{0, 4967266680400950ull};
- i128 expectedRemainder = -i128{0, 5000000ull};
- i128 quotient = dividend / divider;
- i128 reminder = dividend % divider;
- UNIT_ASSERT_EQUAL(quotient, expectedQuotient);
- UNIT_ASSERT_EQUAL(reminder, expectedRemainder);
- }
- Y_UNIT_TEST(ii128DivideAlgoCheck_NegByNeg) {
- /*
- -49672666804009505000000 / -10000000 == 4967266680400950
- -49672666804009505000000 % -10000000 == -5000000
- */
- i128 dividend = -i128{2692ull, 14031757583392049728ull};
- i64 divider = -10000000;
- i128 expectedQuotient = {0, 4967266680400950ull};
- i128 expectedRemainder = -i128{0, 5000000ull};
- i128 quotient = dividend / divider;
- i128 reminder = dividend % divider;
- UNIT_ASSERT_EQUAL(quotient, expectedQuotient);
- UNIT_ASSERT_EQUAL(reminder, expectedRemainder);
- }
- }
|