BigUIntTest.cpp 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275
  1. //-------------------------------------------------------------------------------------------------------
  2. // Copyright (C) Microsoft. All rights reserved.
  3. // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
  4. //-------------------------------------------------------------------------------------------------------
  5. #include "stdafx.h"
  6. #pragma warning(disable:26434) // Function definition hides non-virtual function in base class
  7. #pragma warning(disable:26439) // Implicit noexcept
  8. #pragma warning(disable:26451) // Arithmetic overflow
  9. #pragma warning(disable:26495) // Uninitialized member variable
  10. #include "catch.hpp"
  11. #include "BigUIntTest.h"
  12. #pragma warning(disable:4100) // unreferenced formal parameter
  13. #pragma warning(disable:6387) // suppressing preFAST which raises warning for passing null to the JsRT APIs
  14. #pragma warning(disable:6262) // CATCH is using stack variables to report errors, suppressing the preFAST warning.
  15. namespace BigUIntTest
  16. {
  17. TEST_CASE("Init_Compare", "[BigUIntTest]")
  18. {
  19. uint32 digits[1];
  20. int32 length = 1;
  21. Js::BigUInt bi1, bi2;
  22. BOOL f;
  23. int result;
  24. digits[0] = 0x00001111;
  25. f = bi1.FInitFromRglu(digits, length);
  26. REQUIRE(f);
  27. SECTION("Equal number init from the same array and length")
  28. {
  29. f = bi2.FInitFromRglu(digits, length);
  30. REQUIRE(f);
  31. result = bi1.Compare(&bi2);
  32. CHECK(result == 0);
  33. }
  34. SECTION("Equal number init from other big int number")
  35. {
  36. f = bi2.FInitFromBigint(&bi1);
  37. REQUIRE(f);
  38. result = bi1.Compare(&bi2);
  39. CHECK(result == 0);
  40. }
  41. SECTION("Greater number")
  42. {
  43. digits[0] = 0x00000001;
  44. f = bi2.FInitFromRglu(digits, length);
  45. REQUIRE(f);
  46. result = bi1.Compare(&bi2);
  47. CHECK(result == 1);
  48. }
  49. SECTION("Smaller number")
  50. {
  51. digits[0] = 0x00000001;
  52. f = bi2.FInitFromRglu(digits, length);
  53. REQUIRE(f);
  54. result = bi2.Compare(&bi1);
  55. CHECK(result == -1);
  56. }
  57. }
  58. TEST_CASE("Addition", "[BigUIntTest]")
  59. {
  60. uint32 digits[1], digit1s[2];
  61. int32 length = 1;
  62. Js::BigUInt bi1, bi2, bi3;
  63. BOOL f;
  64. int result;
  65. SECTION("Check 0x33331111 + 0x33331111 = 0x66662222")
  66. {
  67. digits[0] = 0x33331111;
  68. f = bi1.FInitFromRglu(digits, length);
  69. REQUIRE(f);
  70. f = bi2.FInitFromBigint(&bi1);
  71. REQUIRE(f);
  72. f = bi1.FAdd(&bi2);
  73. REQUIRE(f);
  74. digits[0] = 0x66662222;
  75. f = bi3.FInitFromRglu(digits, length);
  76. REQUIRE(f);
  77. result = bi1.Compare(&bi3);
  78. CHECK(result == 0);
  79. }
  80. SECTION("Check 0xffffffff + 0x1 = 0x100000000")
  81. {
  82. digits[0] = 0xffffffff;
  83. f = bi1.FInitFromRglu(digits, length);
  84. REQUIRE(f);
  85. digits[0] = 0x00000001;
  86. f = bi2.FInitFromRglu(digits, length);
  87. REQUIRE(f);
  88. f = bi1.FAdd(&bi2);
  89. digit1s[0] = 0x0;
  90. digit1s[1] = 0x1;
  91. f = bi3.FInitFromRglu(digit1s, 2);
  92. REQUIRE(f);
  93. result = bi1.Compare(&bi3);
  94. CHECK(result == 0);
  95. }
  96. SECTION("Check 0xffffffffffffffff + 0x1 = 0x10000000000000000")
  97. {
  98. digit1s[0] = 0xffffffff;
  99. digit1s[1] = 0xffffffff;
  100. f = bi1.FInitFromRglu(digit1s, 2);
  101. REQUIRE(f);
  102. digits[0] = 0x00000001;
  103. f = bi2.FInitFromRglu(digits, 1);
  104. REQUIRE(f);
  105. f = bi1.FAdd(&bi2);
  106. uint32 digit2s[3];
  107. digit2s[0] = 0x0;
  108. digit2s[1] = 0x0;
  109. digit2s[2] = 0x1;
  110. f = bi3.FInitFromRglu(digit2s, 3);
  111. REQUIRE(f);
  112. result = bi1.Compare(&bi3);
  113. CHECK(result == 0);
  114. }
  115. }
  116. TEST_CASE("Addition_Subtraction_Large_Number", "[BigUIntTest]")
  117. {
  118. const int l1 = 50, l2 = 1;
  119. uint32 digit1s[l1], digit2s[l2];
  120. Js::BigUInt bi1, bi2;
  121. BOOL f;
  122. SECTION("Check 0xf...0xf + 0x1 = 0x1_0x0...0x0")
  123. {
  124. for (int i = 0; i < l1; i++)
  125. {
  126. digit1s[i] = 0xffffffff;
  127. }
  128. f = bi1.FInitFromRglu(digit1s, l1);
  129. REQUIRE(f);
  130. digit2s[0] = 0x1;
  131. f = bi2.FInitFromRglu(digit2s, l2);
  132. REQUIRE(f);
  133. f = bi1.FAdd(&bi2);
  134. REQUIRE(f);
  135. int32 length = bi1.Clu();
  136. CHECK(length == l1 + 1);
  137. uint32 digit = bi1.Lu(length - 1);
  138. CHECK(digit == 1);
  139. for (int i = 0; i < length - 1; i++)
  140. {
  141. digit = bi1.Lu(i);
  142. CHECK(digit == 0);
  143. }
  144. }
  145. }
  146. TEST_CASE("Subtraction", "[BigUIntTest]")
  147. {
  148. uint32 digits[1], digit1s[2];
  149. int32 length = 1;
  150. Js::BigUInt bi1, bi2, bi3;
  151. BOOL f;
  152. int result;
  153. SECTION("Check 0x66662222 - 0x33331111 = 0x33331111")
  154. {
  155. digits[0] = 0x33331111;
  156. f = bi1.FInitFromRglu(digits, length);
  157. REQUIRE(f);
  158. f = bi2.FInitFromBigint(&bi1);
  159. REQUIRE(f);
  160. digits[0] = 0x66662222;
  161. f = bi3.FInitFromRglu(digits, length);
  162. REQUIRE(f);
  163. bi3.Subtract(&bi2);
  164. result = bi1.Compare(&bi3);
  165. CHECK(result == 0);
  166. }
  167. SECTION("Check 0x3_0x1 - 0x1_0x0 = 0x2_0x1")
  168. {
  169. digit1s[0] = 0x1;
  170. digit1s[1] = 0x3;
  171. f = bi3.FInitFromRglu(digit1s, 2);
  172. REQUIRE(f);
  173. digit1s[0] = 0x0;
  174. digit1s[1] = 0x1;
  175. f = bi2.FInitFromRglu(digit1s, 2);
  176. REQUIRE(f);
  177. bi3.Subtract(&bi2);
  178. int l = bi3.Clu();
  179. CHECK(l == 2);
  180. int digit = bi3.Lu(1);
  181. CHECK(digit == 2);
  182. digit = bi3.Lu(0);
  183. CHECK(digit == 1);
  184. }
  185. SECTION("Check 0x2_0x0 - 0x1 = 0x1_0xfffffff")
  186. {
  187. digit1s[0] = 0x0;
  188. digit1s[1] = 0x2;
  189. f = bi3.FInitFromRglu(digit1s, 2);
  190. REQUIRE(f);
  191. digits[0] = 0x1;
  192. f = bi2.FInitFromRglu(digits, 1);
  193. REQUIRE(f);
  194. bi3.Subtract(&bi2);
  195. int l = bi3.Clu();
  196. CHECK(l == 2);
  197. int digit = bi3.Lu(1);
  198. CHECK(digit == 1);
  199. digit = bi3.Lu(0);
  200. CHECK(digit == 0xffffffff);
  201. }
  202. SECTION("Currently 0x1_0x0 - 0x1 is overflow")
  203. {
  204. }
  205. }
  206. TEST_CASE("Init_From_Char_Of_Digits", "[BigUIntTest]")
  207. {
  208. BigUInt biDec;
  209. const char *charDigit;
  210. bool result;
  211. int charDigitLength;
  212. SECTION("2**32-1 should have length = 1")
  213. {
  214. charDigit = "4294967295";
  215. charDigitLength = 10;
  216. result = biDec.FInitFromDigits(charDigit, charDigitLength, &charDigitLength);
  217. REQUIRE(result);
  218. int length = biDec.Clu();
  219. CHECK(length == 1);
  220. uint32 digit = biDec.Lu(0);
  221. CHECK(digit == 4294967295);
  222. }
  223. SECTION("2**32+2 should have length = 2")
  224. {
  225. charDigit = "4294967298";
  226. charDigitLength = 10;
  227. result = biDec.FInitFromDigits(charDigit, charDigitLength, &charDigitLength);
  228. REQUIRE(result);
  229. int length = biDec.Clu();
  230. CHECK(length == 2);
  231. uint32 digit = biDec.Lu(0);
  232. CHECK(digit == 2);
  233. digit = biDec.Lu(1);
  234. CHECK(digit == 1);
  235. }
  236. SECTION("2**64 should have length = 3")
  237. {
  238. charDigit = "18446744073709551616";
  239. charDigitLength = 20;
  240. result = biDec.FInitFromDigits(charDigit, charDigitLength, &charDigitLength);
  241. REQUIRE(result);
  242. int length = biDec.Clu();
  243. CHECK(length == 3);
  244. uint32 digit = biDec.Lu(0);
  245. CHECK(digit == 0);
  246. digit = biDec.Lu(1);
  247. CHECK(digit == 0);
  248. digit = biDec.Lu(2);
  249. CHECK(digit == 1);
  250. }
  251. }
  252. }