00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include <spl/Debug.h>
00018 #include <spl/Log.h>
00019 #include <spl/BigInteger.h>
00020 #include <spl/math/Math.h>
00021 #include <spl/UInt32.h>
00022
00023 #ifdef DEBUG
00024
00025 static void _TestBigIntegerIdentities()
00026 {
00027 {
00028 UNIT_ASSERT("0==0", BigInteger::Zero().Equals((int64)0));
00029 UNIT_ASSERT("1==1", BigInteger::One().Equals((int64)1));
00030 }
00031
00032 DEBUG_CLEAR_MEM_CHECK_POINTS();
00033 DEBUG_DUMP_MEM_LEAKS();
00034 UNIT_ASSERT_MEM_NOTED("BigInteger test 0");
00035
00036 Log::SWriteOkFail( "BigInteger identities test" );
00037 }
00038
00039 static void _TestBigIntegerAddSub()
00040 {
00041 {
00042 RefCountPtr<BigInteger> a = BigInteger::ValueOf(1);
00043 RefCountPtr<BigInteger> b = BigInteger::ValueOf(1);
00044
00045 BigInteger result = *a + *b;
00046 UNIT_ASSERT("1+1", result == 2);
00047 UNIT_ASSERT("1==1", *a == *b);
00048 UNIT_ASSERT("1==1", a->Compare(*b) == 0);
00049 UNIT_ASSERT("! 1!=1", !(*a != *b));
00050 }
00051
00052 DEBUG_CLEAR_MEM_CHECK_POINTS();
00053 DEBUG_DUMP_MEM_LEAKS();
00054 UNIT_ASSERT_MEM_NOTED("BigInteger test 1");
00055
00056 {
00057 RefCountPtr<BigInteger> a = BigInteger::ValueOf(3);
00058 RefCountPtr<BigInteger> b = BigInteger::ValueOf(1);
00059
00060 BigInteger result = *a - *b;
00061 UNIT_ASSERT("3-1", result == 2);
00062 UNIT_ASSERT("3!=1", *a != *b);
00063 UNIT_ASSERT("! 3==1", !(*a == *b));
00064 UNIT_ASSERT("3.Compare(1) > 0", a->Compare(*b) > 0);
00065 UNIT_ASSERT("1.Compare(3) < 0", b->Compare(*a) < 0);
00066 }
00067
00068 DEBUG_CLEAR_MEM_CHECK_POINTS();
00069 DEBUG_DUMP_MEM_LEAKS();
00070 UNIT_ASSERT_MEM_NOTED("BigInteger test 2");
00071
00072 {
00073 RefCountPtr<BigInteger> a = BigInteger::ValueOf(3);
00074 RefCountPtr<BigInteger> b = BigInteger::ValueOf(2);
00075
00076 BigInteger result = *a * *b;
00077 UNIT_ASSERT("3*2", result == 6);
00078 }
00079
00080 DEBUG_CLEAR_MEM_CHECK_POINTS();
00081 DEBUG_DUMP_MEM_LEAKS();
00082 UNIT_ASSERT_MEM_NOTED("BigInteger test 3");
00083
00084 {
00085 RefCountPtr<BigInteger> a = BigInteger::ValueOf(6);
00086 RefCountPtr<BigInteger> b = BigInteger::ValueOf(2);
00087
00088 BigInteger result = *a / *b;
00089 UNIT_ASSERT("6/2", result == 3);
00090 }
00091
00092 DEBUG_CLEAR_MEM_CHECK_POINTS();
00093 DEBUG_DUMP_MEM_LEAKS();
00094 UNIT_ASSERT_MEM_NOTED("BigInteger test 4");
00095
00096 {
00097 RefCountPtr<BigInteger> a = BigInteger::ValueOf(6);
00098 RefCountPtr<BigInteger> b = BigInteger::ValueOf(7);
00099
00100 BigInteger result = *a % *b;
00101 UNIT_ASSERT("6%2", result == 6);
00102 }
00103
00104 DEBUG_CLEAR_MEM_CHECK_POINTS();
00105 DEBUG_DUMP_MEM_LEAKS();
00106 UNIT_ASSERT_MEM_NOTED("BigInteger test 5");
00107
00108 {
00109 RefCountPtr<BigInteger> a = BigInteger::ValueOf(6);
00110
00111 BigInteger result = *a >> 1;
00112 UNIT_ASSERT("6>>1", result == 3);
00113 result = result << 2;
00114 UNIT_ASSERT("3<<2", result == 12);
00115 }
00116
00117 DEBUG_CLEAR_MEM_CHECK_POINTS();
00118 DEBUG_DUMP_MEM_LEAKS();
00119 UNIT_ASSERT_MEM_NOTED("BigInteger test 6");
00120
00121 {
00122 RefCountPtr<BigInteger> a = BigInteger::ValueOf(1);
00123 RefCountPtr<BigInteger> b = BigInteger::ValueOf(2);
00124
00125 BigInteger result = *a | *b;
00126 UNIT_ASSERT("1|2", result == 3);
00127
00128 result = *a & *b;
00129 UNIT_ASSERT("1&2", result == 0);
00130
00131 result = *a ^ *b;
00132 UNIT_ASSERT("1^2", result == 3);
00133 }
00134
00135 DEBUG_CLEAR_MEM_CHECK_POINTS();
00136 DEBUG_DUMP_MEM_LEAKS();
00137 UNIT_ASSERT_MEM_NOTED("BigInteger test 7");
00138
00139 Log::SWriteOkFail( "BigInteger small number bin ops test" );
00140 }
00141
00142 static void _TestBigIntegerToByteArray()
00143 {
00144 {
00145 #if defined(_MSC_VER) && _MSC_VER < 1300
00146 int64 num = 0xFFFFFFFFF;
00147 #else
00148 int64 num = 0xFFFFFFFFFLL;
00149 #endif
00150 RefCountPtr<BigInteger> i = BigInteger::ValueOf(num);
00151 Array<byte> bytes = i->ToByteArrayUnsigned();
00152 BigInteger i2(bytes);
00153
00154 UNIT_ASSERT("i==i2", *i == i2);
00155 UNIT_ASSERT("i2==0xFFFFFFFFFL", i2 == num);
00156
00157 bytes = i->ToByteArray();
00158 i2 = BigInteger(bytes);
00159
00160 UNIT_ASSERT("i==i2", *i == i2);
00161 UNIT_ASSERT("i2==0xFFFFFFFFFL", i2 == num);
00162 }
00163
00164 DEBUG_CLEAR_MEM_CHECK_POINTS();
00165 DEBUG_DUMP_MEM_LEAKS();
00166 UNIT_ASSERT_MEM_NOTED("BigInteger test 0");
00167
00168 Log::SWriteOkFail( "BigInteger ToByteArray() test" );
00169 }
00170
00171 static void _TestBigIntegerModPow()
00172 {
00173 {
00174 int x = 6;
00175 BigInteger bx = *BigInteger::ValueOf(x);
00176 UNIT_ASSERT("6", bx.ToInt() == 6);
00177
00178 int dp = 2;
00179 BigInteger bdp = *BigInteger::ValueOf(dp);
00180
00181 int p = 3;
00182 BigInteger bp = *BigInteger::ValueOf(p);
00183
00184 int iResult = ((int)(Math::Pow((double)x, (double)dp)) % p);
00185 BigInteger bResult = *bx.ModPow(bdp, bp);
00186 UNIT_ASSERT("(x ^ dp) % p", bResult == iResult);
00187
00188 iResult = ((int)(Math::Pow((double)p, (double)dp)) % x);
00189 bResult = *bp.ModPow(bdp, bx);
00190 UNIT_ASSERT("(p ^ dp) % x", bResult == iResult);
00191
00192 int iFive = 5;
00193 BigInteger bFive = *BigInteger::ValueOf(iFive);
00194
00195 iResult = (int)Math::Remainder((double)x, (double)iFive);
00196 bResult = *bx.Remainder(bFive);
00197 UNIT_ASSERT("x % p", bResult == iResult);
00198
00199 bResult = *bx.Mod(bFive);
00200 UNIT_ASSERT("x % p", bResult == iResult);
00201 }
00202 {
00203 int64 m = UInt32::MaxValue();
00204 int64 e = 18;
00205 int64 v = 5;
00206
00207 BigIntegerPtr bm = BigInteger::ValueOf(m);
00208 BigIntegerPtr be = BigInteger::ValueOf(e);
00209 BigIntegerPtr bv = BigInteger::ValueOf(v);
00210
00211 double dRes = Math::Pow((double)v, (double)e);
00212 int64 iRes = (int64)dRes;
00213 iRes = iRes % m;
00214 BigInteger bRes = *bv->ModPow(*be, *bm);
00215
00216 UNIT_ASSERT("no", *bm == m);
00217 UNIT_ASSERT("no", *be == e);
00218 UNIT_ASSERT("no", *bv == v);
00219 UNIT_ASSERT("large int", bRes == iRes);
00220 }
00221
00222 DEBUG_CLEAR_MEM_CHECK_POINTS();
00223 DEBUG_DUMP_MEM_LEAKS();
00224 UNIT_ASSERT_MEM_NOTED("BigInteger test 0");
00225
00226 Log::SWriteOkFail( "BigInteger ModPow ((x ^ dP) % p) test" );
00227 }
00228
00229 static void _TestBigIntegerDivideRemain()
00230 {
00231 int numer = 65535;
00232 int demon = -1919574108;
00233
00234 {
00235 BigInteger bnumer = *BigInteger::ValueOf(numer);
00236 BigInteger bdemon = *BigInteger::ValueOf(demon);
00237
00238
00239 }
00240
00241 DEBUG_CLEAR_MEM_CHECK_POINTS();
00242 DEBUG_DUMP_MEM_LEAKS();
00243 UNIT_ASSERT_MEM_NOTED("BigInteger test 0");
00244
00245 Log::SWriteOkFail( "BigInteger DivideAndRemainder test" );
00246 }
00247
00248 static void _TestBigInteger32Bits()
00249 {
00250 int64 i = UInt32::MaxValue();
00251 int64 j = 65527;
00252
00253 {
00254 BigInteger bi = *BigInteger::ValueOf(i);
00255 BigInteger bj = *BigInteger::ValueOf(j);
00256
00257 UNIT_ASSERT("UInt32::MaxValue()", bi == i);
00258 UNIT_ASSERT("UInt32::MaxValue()", bj == j);
00259 UNIT_ASSERT("UInt32::MaxValue() / 65527", (bi / bj) == i / j);
00260 UNIT_ASSERT("UInt32::MaxValue()", bi == i);
00261 UNIT_ASSERT("UInt32::MaxValue()", bj == j);
00262
00263 int64 ires = j / i;
00264 BigInteger bres = bj / bi;
00265 UNIT_ASSERT("UInt32::MaxValue()", bi == i);
00266 UNIT_ASSERT("UInt32::MaxValue()", bj == j);
00267
00268 int bresi = bres.ToInt();
00269 UNIT_ASSERT("65527 / UInt32::MaxValue()", (bres) == ires);
00270
00271 UNIT_ASSERT("UInt32::MaxValue() % 65527", (bi % bj) == i % j);
00272 UNIT_ASSERT("65527 % UInt32::MaxValue()", (bj % bi) == j % i);
00273
00274 i--;
00275
00276 bi = *BigInteger::ValueOf(i);
00277
00278 UNIT_ASSERT("UInt32::MaxValue() - 1", bi == i);
00279 UNIT_ASSERT("UInt32::MaxValue() - 1 / 65527", (bi / bj) == i / j);
00280 UNIT_ASSERT("65527 / UInt32::MaxValue() - 1", (bj / bi) == j / i);
00281
00282 UNIT_ASSERT("UInt32::MaxValue() - 1 % 65527", (bi % bj) == i % j);
00283 UNIT_ASSERT("65527 % UInt32::MaxValue() - 1", (bj % bi) == j % i);
00284 }
00285
00286 DEBUG_CLEAR_MEM_CHECK_POINTS();
00287 DEBUG_DUMP_MEM_LEAKS();
00288 UNIT_ASSERT_MEM_NOTED("BigInteger test 0");
00289
00290 Log::SWriteOkFail( "BigInteger 32 bit boundry test" );
00291 }
00292
00293 void _TestBigInteger()
00294 {
00295 _TestBigIntegerIdentities();
00296 DEBUG_CLEAR_MEM_CHECK_POINTS();
00297 DEBUG_DUMP_MEM_LEAKS();
00298
00299 _TestBigIntegerAddSub();
00300 DEBUG_CLEAR_MEM_CHECK_POINTS();
00301 DEBUG_DUMP_MEM_LEAKS();
00302
00303 _TestBigIntegerToByteArray();
00304 DEBUG_CLEAR_MEM_CHECK_POINTS();
00305 DEBUG_DUMP_MEM_LEAKS();
00306
00307 _TestBigIntegerModPow();
00308 DEBUG_CLEAR_MEM_CHECK_POINTS();
00309 DEBUG_DUMP_MEM_LEAKS();
00310
00311 _TestBigIntegerDivideRemain();
00312 DEBUG_CLEAR_MEM_CHECK_POINTS();
00313 DEBUG_DUMP_MEM_LEAKS();
00314
00315 _TestBigInteger32Bits();
00316 DEBUG_CLEAR_MEM_CHECK_POINTS();
00317 DEBUG_DUMP_MEM_LEAKS();
00318 }
00319
00320 #endif