• Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

test/TestBigInteger.cpp

00001 /*
00002  *   This file is part of the Standard Portable Library (SPL).
00003  *
00004  *   SPL is free software: you can redistribute it and/or modify
00005  *   it under the terms of the GNU General Public License as published by
00006  *   the Free Software Foundation, either version 3 of the License, or
00007  *   (at your option) any later version.
00008  *
00009  *   SPL is distributed in the hope that it will be useful,
00010  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  *   GNU General Public License for more details.
00013  *
00014  *   You should have received a copy of the GNU General Public License
00015  *   along with SPL.  If not, see <http://www.gnu.org/licenses/>.
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                 //UNIT_ASSERT("65535 / -1919574108",  (bnumer / bdemon) == numer / bdemon);
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