BigInt.cpp 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. // Copyright (c) 2008-2023 the Urho3D project
  2. // License: MIT
  3. #include "../ForceAssert.h"
  4. #include <Urho3D/Container/Str.h>
  5. #include <Urho3D/Math/BigInt.h>
  6. #include <Urho3D/DebugNew.h>
  7. using namespace Urho3D;
  8. void Test_Math_BigInt()
  9. {
  10. // Constructors
  11. assert(BigInt().ToString() == "0");
  12. assert(BigInt(0).ToString() == "0");
  13. assert(BigInt((i32)0x7FFFFFFF).ToString() == "2147483647");
  14. assert(BigInt((u32)0x80000000).ToString() == "2147483648");
  15. assert(BigInt((u32)0xFFFFFFFF).ToString() == "4294967295");
  16. assert(BigInt((i64)0x7FFFFFFFFFFFFFFF).ToString() == "9223372036854775807"); // (i64) need for macOS
  17. assert(BigInt((u64)0x8000000000000000).ToString() == "9223372036854775808"); // (u64) need for macOS
  18. assert(BigInt((u64)0xFFFFFFFFFFFFFFFF).ToString() == "18446744073709551615"); // (u64) need for macOS
  19. assert(BigInt("0").ToString() == "0");
  20. assert(BigInt("-0").ToString() == "0");
  21. assert(BigInt("3").ToString() == "3");
  22. assert(BigInt("-7").ToString() == "-7");
  23. assert(BigInt("123456789").ToString() == "123456789");
  24. assert(BigInt("-123456789").ToString() == "-123456789");
  25. assert(BigInt("123000789").ToString() == "123000789");
  26. assert(BigInt("-1230000").ToString() == "-1230000");
  27. assert(BigInt("0001230000").ToString() == "1230000");
  28. assert(BigInt("-0001230000").ToString() == "-1230000");
  29. {
  30. BigInt bi{"-99999999999999999999999999999999999999999999999999999999999999999999"
  31. "999999999999999999999999999999999999999999999999999999999999999999999"
  32. "999999999999999999999999999999999999999999999999999999999999999999999"};
  33. assert(bi.ToString() ==
  34. "-99999999999999999999999999999999999999999999999999999999999999999999"
  35. "999999999999999999999999999999999999999999999999999999999999999999999"
  36. "999999999999999999999999999999999999999999999999999999999999999999999");
  37. }
  38. // Comparison
  39. assert(BigInt("0") == BigInt("-0"));
  40. assert(BigInt("10") < BigInt("100"));
  41. assert(BigInt("10") > BigInt("-100"));
  42. assert(BigInt("-10") > BigInt("-100"));
  43. // Sum of values with same sign
  44. assert((BigInt("0") + BigInt("0")).ToString() == "0");
  45. assert((BigInt("000") + BigInt("000")).ToString() == "0");
  46. assert((BigInt("1") + BigInt("2")).ToString() == "3");
  47. assert((BigInt("1000") + BigInt("200")).ToString() == "1200");
  48. assert((BigInt("-1000") + BigInt("-234")).ToString() == "-1234");
  49. assert((BigInt("-1000") - BigInt("234")).ToString() == "-1234");
  50. assert((BigInt("-1000") - BigInt("0")).ToString() == "-1000");
  51. assert((BigInt("9999999999999999999999") + BigInt("9999999999999999999999")).ToString() == "19999999999999999999998");
  52. assert((BigInt("9999999999999999999999") + BigInt("1")).ToString() == "10000000000000000000000");
  53. // Sum of values with opposite sign
  54. assert((BigInt("000") - BigInt("000")).ToString() == "0");
  55. assert((BigInt("1000") - BigInt("1000")).ToString() == "0");
  56. assert((BigInt("1000") - BigInt("234")).ToString() == "766");
  57. assert((BigInt("234") - BigInt("1000")).ToString() == "-766");
  58. assert((BigInt("1000") - BigInt("0")).ToString() == "1000");
  59. assert((BigInt("0") - BigInt("034005")).ToString() == "-34005");
  60. assert((BigInt("10000000000000000000000") - BigInt("1")).ToString() == "9999999999999999999999");
  61. assert((BigInt("-10000000000000000000000") + BigInt("1")).ToString() == "-9999999999999999999999");
  62. // Multiply
  63. assert((BigInt("0") * BigInt("0")).ToString() == "0");
  64. assert((BigInt("1") * BigInt("1")).ToString() == "1");
  65. assert((BigInt("1") * BigInt("9999999999999999999999")).ToString() == "9999999999999999999999");
  66. assert((BigInt("0") * BigInt("9999999999999999999999")).ToString() == "0");
  67. assert((BigInt("10") * BigInt("2")).ToString() == "20");
  68. assert((BigInt("-99999") * BigInt("99999")).ToString() == "-9999800001");
  69. {
  70. BigInt bi1{"-99999999999999999999999999999999999999999999999999999999999999999999"};
  71. BigInt bi2{"99999999999999999999999999999999999999999999999999999999999999999999"};
  72. String str = (bi1 * bi2).ToString();
  73. assert(str == "-99999999999999999999999999999999999999999999999999999999999999999998"
  74. "00000000000000000000000000000000000000000000000000000000000000000001");
  75. }
  76. // Divison
  77. assert((BigInt("0") / BigInt("-0")).ToString() == "0");
  78. assert((BigInt("0") % BigInt("0")).ToString() == "0");
  79. assert((BigInt("999999") / 1234).ToString() == "810");
  80. assert((BigInt("999999") % 1234).ToString() == "459");
  81. assert(1234 / BigInt("999999") == 0);
  82. assert(1234 % BigInt("999999") == 1234);
  83. {
  84. // https://en.cppreference.com/w/cpp/language/operator_arithmetic
  85. // (a/b)*b + a%b == a
  86. BigInt a("9999999843");
  87. BigInt b("99999998");
  88. assert(a/b*b + a%b == a);
  89. a = {"-9999999843"};
  90. b = {"99999998"};
  91. assert(a/b*b + a%b == a);
  92. a = {"9999999843"};
  93. b = {"-99999998"};
  94. assert(a/b*b + a%b == a);
  95. a = {"-9999999843"};
  96. b = {"-99999998"};
  97. assert(a/b*b + a%b == a);
  98. }
  99. #if false // Current division implementation too slow
  100. {
  101. BigInt num{"-99999999999999999999999999999999999999999999999999999999999999999998"
  102. "00000000000000000000000000000000000000000000000000000000000000000001"};
  103. BigInt denom{"-99999999999999999999999999999999999999999999999999999999999999999999"};
  104. String str = (num / denom).ToString();
  105. assert(str == "99999999999999999999999999999999999999999999999999999999999999999999");
  106. str = (num % denom).ToString();
  107. assert(str == "0");
  108. }
  109. #else
  110. {
  111. BigInt num{"-999998"
  112. "000001"};
  113. BigInt denom{"-999999"};
  114. String str = (num / denom).ToString();
  115. assert(str == "999999");
  116. str = (num % denom).ToString();
  117. assert(str == "0");
  118. }
  119. #endif
  120. // Additional operators
  121. {
  122. BigInt bi{(i32)1};
  123. assert((bi++).ToString() == "1");
  124. assert(bi.ToString() == "2");
  125. assert((++bi).ToString() == "3");
  126. assert(bi.ToString() == "3");
  127. assert((bi--).ToString() == "3");
  128. assert(bi.ToString() == "2");
  129. assert((--bi).ToString() == "1");
  130. assert(bi.ToString() == "1");
  131. assert((bi += 10).ToString() == "11");
  132. assert((bi -= 2).ToString() == "9");
  133. assert((bi *= 2).ToString() == "18");
  134. }
  135. }