X-Git-Url: https://mattmccutchen.net/bigint/bigint.git/blobdiff_plain/e6866cd00f91dd02fb54942d61fb1586ce0ed5b5..79881c050bfa025ac58e0940c496592d857e3044:/testsuite.cc diff --git a/testsuite.cc b/testsuite.cc index a831fbc..7cb9768 100644 --- a/testsuite.cc +++ b/testsuite.cc @@ -55,11 +55,39 @@ TEST(10); //10 // TODO: Comprehensively test the general and special cases of each function. -// Default constructors +// === Default constructors === + TEST(check(BigUnsigned())); //0 TEST(check(BigInteger())); //0 -// BigUnsigned conversion limits +// === Block-array constructors === + +BigUnsigned::Blk myBlocks[3]; +myBlocks[0] = 3; +myBlocks[1] = 4; +myBlocks[2] = 0; +BigUnsigned bu(myBlocks, 3); +TEST(check(bu)); //17179869187 +TEST(check(BigInteger(myBlocks, 3))); //17179869187 +TEST(check(BigInteger(bu ))); //17179869187 + +// For nonzero magnitude, reject zero and invalid signs. +TEST(check(BigInteger(myBlocks, 3, BigInteger::positive))); //17179869187 +TEST(check(BigInteger(myBlocks, 3, BigInteger::negative))); //-17179869187 +TEST(check(BigInteger(myBlocks, 3, BigInteger::zero ))); //error +TEST(check(BigInteger(bu, BigInteger::positive))); //17179869187 +TEST(check(BigInteger(bu, BigInteger::negative))); //-17179869187 +TEST(check(BigInteger(bu, BigInteger::zero ))); //error + +// For zero magnitude, force the sign to zero without error. +BigUnsigned::Blk myZeroBlocks[1]; +myZeroBlocks[0] = 0; +TEST(check(BigInteger(myZeroBlocks, 1, BigInteger::positive))); //0 +TEST(check(BigInteger(myZeroBlocks, 1, BigInteger::negative))); //0 +TEST(check(BigInteger(myZeroBlocks, 1, BigInteger::zero ))); //0 + +// === BigUnsigned conversion limits === + TEST(BigUnsigned(0).toUnsignedLong()); //0 TEST(BigUnsigned(4294967295U).toUnsignedLong()); //4294967295 TEST(stringToBigUnsigned("4294967296").toUnsignedLong()); //error @@ -85,7 +113,8 @@ TEST(BigUnsigned(0).toShort()); //0 TEST(BigUnsigned(32767).toShort()); //32767 TEST(BigUnsigned(32768).toShort()); //error -// BigInteger conversion limits +// === BigInteger conversion limits === + TEST(BigInteger(-1).toUnsignedLong()); //error TEST(BigInteger(0).toUnsignedLong()); //0 TEST(BigInteger(4294967295U).toUnsignedLong()); //4294967295 @@ -123,7 +152,8 @@ TEST(BigInteger(0).toShort()); //0 TEST(BigInteger(32767).toShort()); //32767 TEST(BigInteger(32768).toShort()); //error -// Negative BigUnsigneds +// === Negative BigUnsigneds === + // ...during construction TEST(BigUnsigned(short(-1))); //error TEST(BigUnsigned(pathologicalShort)); //error @@ -131,6 +161,7 @@ TEST(BigUnsigned(-1)); //error TEST(BigUnsigned(pathologicalInt)); //error TEST(BigUnsigned(long(-1))); //error TEST(BigUnsigned(pathologicalLong)); //error + // ...during subtraction TEST(BigUnsigned(5) - BigUnsigned(6)); //error TEST(stringToBigUnsigned("314159265358979323") - stringToBigUnsigned("314159265358979324")); //error @@ -138,7 +169,8 @@ TEST(check(BigUnsigned(5) - BigUnsigned(5))); //0 TEST(check(stringToBigUnsigned("314159265358979323") - stringToBigUnsigned("314159265358979323"))); //0 TEST(check(stringToBigUnsigned("4294967296") - BigUnsigned(1))); //4294967295 -// Addition +// === BigUnsigned addition === + TEST(check(BigUnsigned(0) + 0)); //0 TEST(check(BigUnsigned(0) + 1)); //1 // Ordinary carry @@ -147,7 +179,8 @@ TEST(check(stringToBigUnsigned("8589934591" /* 2^33 - 1*/) // Creation of a new block TEST(check(BigUnsigned(0xFFFFFFFFU) + 1)); //4294967296 -// Subtraction +// === BigUnsigned subtraction === + TEST(check(BigUnsigned(1) - 0)); //1 TEST(check(BigUnsigned(1) - 1)); //0 TEST(check(BigUnsigned(2) - 1)); //1 @@ -157,7 +190,8 @@ TEST(check(stringToBigUnsigned("12884901889") // Borrow that removes a block TEST(check(stringToBigUnsigned("4294967296") - 1)); //4294967295 -// Multiplication and division +// === BigUnsigned multiplication and division === + BigUnsigned a = check(BigUnsigned(314159265) * 358979323); TEST(a); //112776680263877595 TEST(a / 123); //916883579381118 @@ -165,6 +199,60 @@ TEST(a % 123); //81 TEST(BigUnsigned(5) / 0); //error +// === Block accessors === + +BigUnsigned b; +TEST(b); //0 +TEST(b.getBlock(0)); //0 +b.setBlock(1, 314); +// Did b grow properly? And did we zero intermediate blocks? +TEST(check(b)); //1348619730944 +TEST(b.getLength()); //2 +TEST(b.getBlock(0)); //0 +TEST(b.getBlock(1)); //314 +// Did b shrink properly? +b.setBlock(1, 0); +TEST(check(b)); //0 + +BigUnsigned bb(314); +bb.setBlock(1, 159); +// Make sure we used allocateAndCopy, not allocate +TEST(bb.getBlock(0)); //314 +TEST(bb.getBlock(1)); //159 +// Blocks beyond the number should be zero regardless of whether they are +// within the capacity. +bb.add(1, 2); +TEST(bb.getBlock(0)); //3 +TEST(bb.getBlock(1)); //0 +TEST(bb.getBlock(2)); //0 +TEST(bb.getBlock(314159)); //0 + +// === Bit accessors === + +TEST(BigUnsigned(0).bitLength()); //0 +TEST(BigUnsigned(1).bitLength()); //1 +TEST(BigUnsigned(4095).bitLength()); //12 +TEST(BigUnsigned(4096).bitLength()); //13 +// 5 billion is between 2^32 (about 4 billion) and 2^33 (about 8 billion). +TEST(stringToBigUnsigned("5000000000").bitLength()); //33 + +// 25 is binary 11001. +BigUnsigned bbb(25); +TEST(bbb.getBit(4)); //1 +TEST(bbb.getBit(3)); //1 +TEST(bbb.getBit(2)); //0 +TEST(bbb.getBit(1)); //0 +TEST(bbb.getBit(0)); //1 +TEST(bbb.bitLength()); //5 +// Effectively add 2^32. +bbb.setBit(32, true); +TEST(bbb); //4294967321 +bbb.setBit(31, true); +bbb.setBit(32, false); +TEST(check(bbb)); //2147483673 + +// === Combining BigUnsigned, BigInteger, and primitive integers === + BigUnsigned p1 = BigUnsigned(3) * 5; TEST(p1); //15 /* In this case, we would like g++ to implicitly promote the BigUnsigned to a @@ -177,6 +265,8 @@ TEST(p1); //15 BigInteger p2 = BigInteger(BigUnsigned(3)) * -5; TEST(p2); //-15 +// === Test some previous bugs === + { /* Test that BigInteger division sets the sign to zero. * Bug reported by David Allen. */ @@ -221,6 +311,13 @@ TEST(p2); //-15 TEST(check(num)); //25 } +{ + /* Test that BigUnsignedInABase(std::string) constructor rejects digits + * too big for the specified base. + * Bug reported by Niakam Kazemi. */ + TEST(BigUnsignedInABase("f", 10)); //error +} + } catch (const char *err) { cout << "UNCAUGHT ERROR: " << err << endl; }