1 /*==============================================================================
   2 |
   3 |  NAME
   4 |
   5 |     ppUnitTest.cpp
   6 |
   7 |  DESCRIPTION
   8 |
   9 |     Unit test for exercising all classes and methods.
  10 |     User manual and technical documentation are described in detail in my web page at
  11 |
  12 |         http://seanerikoconnor.freeservers.com/Mathematics/AbstractAlgebra/PrimitivePolynomials/overview.html
  13 |
  14 |  LEGAL
  15 |
  16 |     Primpoly Version 16.1 - A Program for Computing Primitive Polynomials.
  17 |     Copyright (C) 1999-2021 by Sean Erik O'Connor.  All Rights Reserved.
  18 |
  19 |     This program is free software: you can redistribute it and/or modify
  20 |     it under the terms of the GNU General Public License as published by
  21 |     the Free Software Foundation, either version 3 of the License, or
  22 |     (at your option) any later version.
  23 |
  24 |     This program is distributed in the hope that it will be useful,
  25 |     but WITHOUT ANY WARRANTY; without even the implied warranty of
  26 |     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  27 |     GNU General Public License for more details.
  28 |
  29 |     You should have received a copy of the GNU General Public License
  30 |     along with this program.  If not, see http://www.gnu.org/licenses/.
  31 |     
  32 |     The author's address is seanerikoconnor!AT!gmail!DOT!com
  33 |     with the !DOT! replaced by . and the !AT! replaced by @
  34 |
  35 ==============================================================================*/
  36 
  37 
  38 /*------------------------------------------------------------------------------
  39 |                                Includes                                      |
  40 ------------------------------------------------------------------------------*/
  41 
  42 #include <cstdlib>      // abort()
  43 #include <iostream>     // Basic stream I/O.
  44 #include <iomanip>      // I/O manipulators.
  45 #include <new>          // set_new_handler()
  46 #include <cmath>        // Basic math functions e.g. sqrt()
  47 #include <limits>       // Numeric limits.
  48 #include <complex>      // Complex data type and operations.
  49 #include <fstream>      // File stream I/O.
  50 #include <sstream>      // String stream I/O.
  51 #include <vector>       // STL vector class.
  52 #include <string>       // STL string class.
  53 #include <algorithm>    // Iterators.
  54 #include <stdexcept>    // Exceptions.
  55 #include <cassert>      // assert()
  56 #include <array>        // array type.
  57 
  58 using namespace std ;   // So we don't need to say std::vector everywhere.
  59 
  60 
  61 /*------------------------------------------------------------------------------
  62 |                                PP Include Files                              |
  63 ------------------------------------------------------------------------------*/
  64 
  65 #include "Primpoly.h"         // Global functions.
  66 #include "ppArith.h"          // Basic arithmetic functions.
  67 #include "ppBigInt.h"         // Arbitrary precision integer arithmetic.
  68 #include "ppOperationCount.h" // OperationCount collection for factoring and poly finding.
  69 #include "ppFactor.h"         // Prime factorization and Euler Phi.
  70 #include "ppPolynomial.h"     // Polynomial operations and mod polynomial operations.
  71 #include "ppParser.h"         // Parsing of polynomials and I/O services.
  72 
  73 
  74 #ifdef SELF_CHECK
  75 #include "ppUnitTest.h"       // Complete unit test.
  76 
  77 /*=============================================================================
  78  |
  79  | NAME
  80  |
  81  |     UnitTest
  82  |
  83  | DESCRIPTION
  84  |
  85  |     Constructor for the class with a default file name.
  86  |
  87  | EXAMPLE
  88  |
  89  |    try
  90  |    {
  91  |        UnitTest unitTest ;
  92  |        if (!unitTest.run())
  93  |            cerr << "Failed one or more unit tests!" << endl ;
  94  |    }
  95  |    catch( UnitTestError & e )
  96  |    {
  97  |        cerr << "Failed to run unit test suite at all!" << endl ;
  98  |        cerr << e.what() << endl ;
  99  |    }
 100  |
 101  +============================================================================*/
 102 
 103 UnitTest::UnitTest( const char * fileName )
 104         : unit_test_log_file_name_( fileName )
 105 {
 106     // Place results into a log file in the current directory.
 107     // If the file can't be opened, just print results to the console.
 108     fout_.open( unit_test_log_file_name_ ) ;
 109 
 110     // Test this section of code by making the existing file read only:
 111     //     chmod 000 unitTest.log
 112     if (!fout_)
 113     {
 114         cerr << "Unit test:  cannot open output log file " << unit_test_log_file_name_ << endl ;
 115         cerr << "Trying standard output to the console instead." << endl ;
 116 
 117         // Test this section of code by changing "/dev/stdout to "/dev/nonsensewonsense/stdout" and recompiling.
 118         fout_.open( "/dev/stdout", fstream::out ) ;
 119 
 120         if (fout_.fail())
 121         {
 122             ostringstream os ;
 123             os << "Unit test:  cannot open the output log file " << unit_test_log_file_name_
 124                << " and unable to log standard output to the console. "
 125                << "Skipping the unit test self check" ;
 126             throw UnitTestError( os.str(), __FILE__, __LINE__ ) ;
 127         }
 128     }
 129 
 130     fout_ << "\nBegin unit testing..." ;
 131 }
 132 
 133 
 134 /*=============================================================================
 135  |
 136  | NAME
 137  |
 138  |     ~UnitTest
 139  |
 140  | DESCRIPTION
 141  |
 142  |     Destructor which closes the file.
 143  |
 144  +============================================================================*/
 145 
 146 UnitTest::~UnitTest()
 147 {
 148     fout_.close() ;
 149 }
 150 
 151 
 152 /*=============================================================================
 153 |
 154 | NAME
 155 |
 156 |     run
 157 |
 158 | DESCRIPTION
 159 |
 160 |     Run all the unit tests.  Return the overall test status.
 161 |
 162 +============================================================================*/
 163 
 164 bool UnitTest::run()
 165 {
 166     bool status = true ;
 167 
 168     try
 169     {
 170         // A C++ array is more lightweight and faster than a vector for this simple application.
 171         array<bool,8> unitTestStatus ;
 172         unitTestStatus.fill( true ) ;
 173         int i = 0 ;
 174 
 175         // Go thorough all the unit tests in order.
 176         unitTestStatus[i++] = unitTestSystemFunctions() ;
 177         unitTestStatus[i++] = unitTestBigIntBase10() ;
 178         unitTestStatus[i++] = unitTestBigIntDefaultBase() ;
 179         unitTestStatus[i++] = unitTestModPArithmetic() ;
 180         unitTestStatus[i++] = unitTestFactoring() ;
 181         unitTestStatus[i++] = unitTestPolynomials() ;
 182         unitTestStatus[i++] = unitTestPolynomialOrder() ;
 183         unitTestStatus[i++] = unitTestParser() ;
 184 
 185         // True only if every single test passes.
 186         for (i = 0 ;  i < unitTestStatus.size() ;  ++i)
 187             status = status && unitTestStatus[ i ] ;
 188     }
 189     // One or more unit tests might throw an exception unexpectedly.
 190     // This would be a bug since any unit test should catch and handle any exceptions it generates within
 191     // the test itself and convert to a proper test status.
 192     //
 193     // Catch blocks should be in order from more specific to less specific, i.e. up the class hierarchy.
 194     catch( PrimpolyError & e )
 195     {
 196         fout_ << ".........FAIL!\n    caught exception type  PrimpolyError: [ " << e.what() << " ] " << endl ;
 197         status = false ;
 198     }
 199     catch( ParserError & e )
 200     {
 201         fout_ << ".........FAIL!\n    caught exception type  ParserError: [ " << e.what() << " ] " << endl ;
 202         status = false ;
 203     }
 204     catch( FactorError & e )
 205     {
 206         fout_ << ".........FAIL!" << endl ;
 207         fout_ << "    caught FactorError: [ " << e.what() << " ] " << endl ;
 208         status = false ;
 209     }
 210     catch( BigIntRangeError & e )
 211     {
 212         fout_ << ".........FAIL!\n    caught exception type  BigIntRangeError: [ " << e.what() << " ] " << endl ;
 213         status = false ;
 214     }
 215     catch( BigIntDomainError & e )
 216     {
 217         fout_ << ".........FAIL!\n    caught exception type  BigIntDomainError: [ " << e.what() << " ] " << endl ;
 218         status = false ;
 219     }
 220     catch( BigIntUnderflow & e )
 221     {
 222         fout_ << ".........FAIL!\n    caught exception type  BigIntUnderflow: [ " << e.what() << " ] " << endl ;
 223         status = false ;
 224     }
 225     catch( BigIntOverflow & e )
 226     {
 227         fout_ << ".........FAIL!\n    caught exception type  BigIntOverflow: [ " << e.what() << " ] " << endl ;
 228         status = false ;
 229     }
 230     catch( BigIntZeroDivide & e )
 231     {
 232         fout_ << ".........FAIL!\n    caught exception type  BigIntZeroDivide: [ " << e.what() << " ] " << endl ;
 233         status = false ;
 234     }
 235     catch( BigIntMathError & e )
 236     {
 237         fout_ << ".........FAIL!\n    caught exception type  BigIntMathError: [ " << e.what() << " ] " << endl ;
 238         status = false ;
 239     }
 240     catch( ArithModPError & e )
 241     {
 242         fout_ << ".........FAIL!\n    caught exception type  ArithModPError: [ " << e.what() << " ] " << endl ;
 243         status = false ;
 244     }
 245     catch( PolynomialRangeError & e )
 246     {
 247         fout_ << ".........FAIL!\n    caught exception type  PolynomialRangeError: [ " << e.what() << " ] " << endl ;
 248         status = false ;
 249     }
 250     catch( PolynomialError & e )
 251     {
 252         fout_ << ".........FAIL!\n    caught exception type  PolynomialError: [ " << e.what() << " ] " << endl ;
 253         status = false ;
 254     }
 255     //
 256     // Standard library exceptions.
 257     //
 258     catch( bad_alloc & e )
 259     {
 260         fout_ << ".........FAIL!\n    caught exception type  Caught bad_alloc exception: [ " << e.what() << " ] " << endl ;
 261         status = false ;
 262     }
 263     catch( length_error & e )
 264     {
 265         fout_ << ".........FAIL!\n    caught exception type  Caught length_error exception: [ " << e.what() << " ] " << endl ;
 266         status = false ;
 267     }
 268     catch( exception & e )
 269     {
 270         fout_ << ".........FAIL!\n    caught exception type  Standard library error: [ " << e.what() << " ] " << endl ;
 271         status = false ;
 272     }
 273     // Catch all other uncaught exceptions, which would otherwise call terminate()
 274     // which in turn calls abort() and which would halt this program.
 275     //
 276     // Limitations:
 277     // We can't handle the case where terminate() gets called because the
 278     // exception mechanism finds a corrupt stack or catches a destructor
 279     // throwing an exception.
 280     //
 281     // Also we can't catch exceptions which are thrown by initializing or
 282     // destructing global variables.
 283     catch( ... )
 284     {
 285         fout_ << ".........FAIL!\n    caught exception type  uncaught exception" << endl ;
 286         status = false ;
 287     }
 288 
 289     fout_ << "\nEnd unit testing..." ;
 290 
 291     if (status)
 292         fout_ << "\nCONGRATULATIONS!  All tests passed!" << endl ;
 293     else
 294         fout_ << "\nSORRY.  One or more unit tests failed!" << endl ;
 295 
 296     fout_.close() ;
 297 
 298     return status ;
 299 }
 300 
 301 
 302 bool UnitTest::unitTestSystemFunctions()
 303 {
 304     bool status = true ;
 305 
 306     #ifdef DEBUG_PP_FORCE_MEMORY_OVERLOAD
 307     // Test resize() exceptions.
 308     fout_ << "\nTEST:  C++ resize a vector to > max_size dimensions.  Did resize throw a length_error exception?" ;
 309 
 310     //            30
 311     // Typically 2  - 1.
 312     vector<ppuint> testVector ;
 313     size_t maxSize = testVector.max_size() ;
 314 
 315     try
 316     {
 317         // Overload the vector.
 318         testVector.resize( maxSize + 1 ) ;
 319 
 320         fout_ << ".........FAIL!" << endl ;
 321         fout_ << "    resize did not throw an exception " << endl ;
 322         status = false ;
 323     }
 324     catch( length_error & e )
 325     {
 326         fout_ << ".........PASS!" ;
 327     }
 328     catch( ... )
 329     {
 330         fout_ << ".........FAIL!" << endl ;
 331         fout_ << "    resize did not throw a length_error exception" << endl ;
 332         status = false ;
 333     }
 334     #endif // DEBUG_PP_FORCE_MEMORY_OVERLOAD
 335 
 336     #ifdef DEBUG_PP_FORCE_MEMORY_OVERLOAD
 337     fout_ << "\nTEST:  C++ overload memory for a vector.  Did push_back throw an exception?" ;
 338     try
 339     {
 340         // Overload memory.
 341         for (int i = 1 ;  i <= maxSize + 1 ;  ++i)
 342             testVector.push_back( 1000 ) ;
 343 
 344         fout_ << ".........FAIL!" << endl ;
 345         fout_ << "    push_back did not throw an exception" << endl ;
 346         status = false ;
 347     }
 348     catch( bad_alloc & e )
 349     {
 350         fout_ << ".........PASS!" ;
 351     }
 352     catch( ... )
 353     {
 354         fout_ << ".........FAIL!" << endl ;
 355         fout_ << "    push_back did not throw a bad_alloc exception" << endl ;
 356         status = false ;
 357     }
 358     #endif // DEBUG_OVERLOADING_MEMORY
 359 
 360     return status ;
 361 }
 362 
 363 
 364 
 365 bool UnitTest::unitTestBigIntBase10()
 366 {
 367     bool status = true ;
 368 
 369     // ------------------- Set to base 10 ----------------------
 370     ppuint oldBase = 0 ; // Save the old default base.
 371     {
 372         // Instantiate a BigInt object and set its to base 10 to change the base for all BigInts.
 373         BigInt w ;
 374         oldBase = BigInt::getBase() ;
 375         setBase( w, 10 ) ;
 376     }
 377 
 378     #ifdef DEBUG_PP_FORCE_UNIT_TEST_FAIL
 379     { BigInt dummy ; setBase( dummy, 11 ) ; }
 380     #endif
 381 
 382     fout_ << "\nTEST:  BigInt switching from base = " << oldBase << " to new base = " << 10 ;
 383     {
 384         // Check all BigInts have the new base of 10.
 385         if (BigInt::getBase() != 10)
 386         {
 387             fout_ << ".........FAIL!" << endl ;
 388             fout_ << "    Current base is not 10 but rather = " << BigInt::getBase() << endl ;
 389             status = false ;
 390         }
 391         else
 392             fout_ << ".........PASS!" ;
 393     }
 394 
 395     fout_ << "\nTEST:  BigInt u default constructor which gives u = 0." ;
 396     {
 397         BigInt u ;
 398         if (getNumDigits(u) != 0)
 399         {
 400             fout_ << ".........FAIL!" << endl ;
 401             fout_ << "    u = " ; printNumber( u, fout_ ) ; fout_ << endl ;
 402             status = false ;
 403         }
 404         else
 405             fout_ << ".........PASS!" ;
 406     }
 407 
 408     fout_ << "\nTEST:  Constructor BigInt u( d ) from ppuint d = 1234" ;
 409     {
 410         ppuint d{ 1234 } ;
 411         BigInt u( d ) ;
 412         if (getNumDigits( u ) == 4 && getDigit( u, 3 ) == 1 && getDigit( u, 2 ) == 2 && getDigit( u, 1 ) == 3 && getDigit( u, 0 ) == 4)
 413             fout_ << ".........PASS!" ;
 414         else
 415         {
 416             fout_ << ".........FAIL!" << endl ;
 417             fout_ << "    u = " ; printNumber( u, fout_ ) ; fout_ << endl ;
 418             status = false ;
 419         }
 420     }
 421 
 422     fout_ << "\nTEST:  Constructor BigInt u( s ) from string s = \"1234\"" ;
 423     {
 424         string s = "1234" ;
 425         BigInt u( s ) ;
 426         if (getNumDigits( u ) == 4 && getDigit( u, 3 ) == 1 && getDigit( u, 2 ) == 2 && getDigit( u, 1 ) == 3 && getDigit( u, 0 ) == 4)
 427             fout_ << ".........PASS!" ;
 428         else
 429         {
 430             fout_ << ".........FAIL!" << endl ;
 431             fout_ << "    u = " ; printNumber( u, fout_ ) ; fout_ << endl ;
 432             status = false ;
 433         }
 434     }
 435 
 436     fout_ << "\nTEST:  Constructor BigInt u( s ) from INVALID string s = \"12x34\"" ;
 437     try
 438     {
 439         string s = "12x34" ;
 440         BigInt u( s ) ;
 441         fout_ << ".........FAIL!" << endl ;
 442         fout_ << "    u = " ; printNumber( u, fout_ ) ; fout_ << endl ;
 443         status = false ;
 444     }
 445     catch( BigIntRangeError & e )
 446     {
 447         fout_ << ".........PASS!" ;
 448     }
 449 
 450     fout_ << "\nTEST:  Copy constructor BigInt v( u ) from BigInt u( 123 )" ;
 451     {
 452         BigInt u( 123u ) ;
 453         BigInt v( u ) ;
 454 
 455         if (getNumDigits( u ) != getNumDigits( v ) ||
 456             getDigit( u, 0 ) != getDigit( v, 0 ) ||
 457             getDigit( u, 1 ) != getDigit( v, 1 ) ||
 458             getDigit( u, 2 ) != getDigit( v, 2 ))
 459         {
 460             fout_ << ".........FAIL!" << endl ;
 461             fout_ << " u = " ;  printNumber( u, fout_ ) ; fout_ << endl ;
 462             fout_ << " v = " ;  printNumber( v, fout_ ) ; fout_ << endl ;
 463             status = false ;
 464         }
 465         else
 466             fout_ << ".........PASS!" ;
 467     }
 468 
 469     fout_ << "\nTEST:  Assignment operator v = u from BigInt v and BigInt u( 123 )" ;
 470     {
 471         BigInt u( 123u ) ;
 472         BigInt v ; // Don't use BigInt v = u because that would call the copy constructor.
 473         v = u ;
 474 
 475         if (getNumDigits( u ) != getNumDigits( v ) ||
 476             getDigit( u, 0 ) != getDigit( v, 0 ) ||
 477             getDigit( u, 1 ) != getDigit( v, 1 ) ||
 478             getDigit( u, 2 ) != getDigit( v, 2 ))
 479         {
 480             fout_ << ".........FAIL!" << endl ;
 481             fout_ << "    u = " ; printNumber( u, fout_ ) ; fout_ << endl ;
 482             fout_ << "    v = " ; printNumber( v, fout_ ) ; fout_ << endl ;
 483             status = false ;
 484         }
 485         else
 486             fout_ << ".........PASS!" ;
 487     }
 488 
 489     fout_ << "\nTEST:  Implicit casting ppuint d = u from BigInt u( \"01234\" )" ;
 490     {
 491         BigInt u( "01234" ) ;
 492         ppuint d = u ;
 493         if (d != static_cast<ppuint>(1234u))
 494         {
 495             fout_ << ".........FAIL!" << endl ;
 496             fout_ << " u = " ;  printNumber( u, fout_ ) ; fout_ << endl ;
 497             fout_ << " d = "  << d << endl ;
 498             status = false ;
 499         }
 500         else
 501             fout_ << ".........PASS!" ;
 502 
 503         fout_ << "\nTEST:  Explicit casting static_cast< ppuint >( u ) from BigInt u( \"01234\" )" ;
 504         if (static_cast< ppuint >( u ) != static_cast< ppuint >( 1234u ))
 505         {
 506             fout_ << ".........FAIL!" << endl ;
 507             fout_ << "    u = " << endl ; printNumber( u, fout_ ) ; fout_ << endl ;
 508             fout_ << "    static_cast< ppuint > u  = "  << static_cast< ppuint >( u ) << endl ;
 509             status = false ;
 510         }
 511         else
 512             fout_ << ".........PASS!" ;
 513     }
 514 
 515     fout_ << "\nTEST:  Check overflow during ui = static_cast< ppuint >(u) on BigInt u( \"3141592653589793238462643383279\" )" ;
 516     try
 517     {
 518         BigInt u( "3141592653589793238462643383279" ) ;
 519         ppuint ui{ static_cast<ppuint>(u) } ;
 520 
 521         fout_ << ".........FAIL!" << endl ;
 522         fout_ << "    Casting BigInt to ppuint didn't overflow." << endl ;
 523         fout_ << "    u = " ;  printNumber( u, fout_ ) ;  fout_ << endl ;
 524         fout_ << "    ui = " << ui << endl ;
 525         status = false ;
 526     }
 527     catch( BigIntOverflow & e )
 528     {
 529         // Should overflow!
 530         fout_ << ".........PASS!" ;
 531     }
 532 
 533     fout_ << "\nTEST:  Stream output os << u from BigInt u( \"1234567890\" )" ;
 534     {
 535         BigInt u( "1234567890" ) ;
 536         ostringstream os ;
 537         os << u ;
 538         if (os.str() != "1234567890")
 539         {
 540             fout_ << ".........FAIL!" << endl ;
 541             fout_ << "    u = |" << u << "|" << endl ;
 542             fout_ << "    os.str() = |" << os.str() << "|" << endl ;
 543             status = false ;
 544         }
 545         else
 546             fout_ << ".........PASS!" ;
 547     }
 548 
 549     fout_ << "\nTEST:  Stream input is >> u for BigInt u where we've loaded the stream is.str( \"314159265358979323846264\" )" ;
 550     {
 551         BigInt u ;
 552         istringstream is ;
 553         is.clear() ;
 554         is.str( "314159265358979323846264" ) ;
 555         is >> u ;
 556 
 557         // Test by streaming out the BigInt and checking its string value.
 558         ostringstream os ;
 559         os << u ;
 560         if (os.str() != "314159265358979323846264" )
 561         {
 562             fout_ << ".........FAIL!" << endl ;
 563             fout_ << "    BigInt = |" << u << "| is.str() = |" << is.str() << "|" << endl ;
 564             status = false ;
 565         }
 566         else
 567             fout_ << ".........PASS!" ;
 568     }
 569 
 570     fout_ << "\nTEST:  Equality test BigInt u == ppuint d?" ;
 571     {
 572         BigInt u( "9" ) ;
 573         ppuint d{ 9 } ;
 574         if (u == d)
 575             fout_ << ".........PASS!" ;
 576         else
 577         {
 578             fout_ << ".........FAIL!" << endl ;
 579             fout_ << "    u = " ; printNumber( u, fout_ ) ; fout_ << endl ;
 580             fout_ << "    d = " << d << endl ;
 581             status = false ;
 582         }
 583     }
 584 
 585     fout_ << "\nTEST:  Equality test BigInt u == BigInt v" ;
 586     {
 587         BigInt u( "1234" ) ;
 588         BigInt v( "1234" ) ;
 589         if (u == v)
 590             fout_ << ".........PASS!" ;
 591         else
 592         {
 593             fout_ << ".........FAIL!" << endl ;
 594             fout_ << "    u = " ; printNumber( u, fout_ ) ; fout_ << endl ;
 595             fout_ << "    v = " ; printNumber( v, fout_ ) ; fout_ << endl ;
 596             status = false ;
 597         }
 598     }
 599 
 600     fout_ << "\nTEST:  BigInt u > BigInt v" ;
 601     {
 602         BigInt u( "3844035" ) ;
 603         BigInt v( "933134" ) ;
 604 
 605         if (u > v)
 606             fout_ << ".........PASS!" ;
 607         else
 608         {
 609             fout_ << ".........FAIL!" << endl ;
 610             fout_ << "    u = " ; printNumber( u, fout_ ) ; fout_ << endl ;
 611             fout_ << "    v = " ; printNumber( v, fout_ ) ; fout_ << endl ;
 612             status = false ;
 613         }
 614     }
 615 
 616     fout_ << "\nTEST:  BigInt u( \"1234\" ) -= ppuint d" ;
 617     try
 618     {
 619         BigInt u( "1234" ) ;
 620         ppuint d = static_cast<ppuint>(5u) ;
 621         u -= d ;
 622 
 623         if (getNumDigits( u ) != static_cast<ppuint>(4) ||
 624             getDigit( u, 3 )  != static_cast<ppuint>(1) || getDigit( u, 2 ) != static_cast<ppuint>(2) ||
 625             getDigit( u, 1 )  != static_cast<ppuint>(2) || getDigit( u, 0 ) != static_cast<ppuint>(9)
 626            )
 627         {
 628             fout_ << ".........FAIL!" << endl ;
 629             fout_ << "    u = " ; printNumber( u, fout_ ) ; fout_ << endl ;
 630             fout_ << "    d = " << d << endl ;
 631             status = false ;
 632         }
 633         else
 634             fout_ << ".........PASS!" ;
 635     }
 636     catch( BigIntMathError & e )
 637     {
 638         fout_ << ".........FAIL!" << endl ;
 639         fout_ << "BigIntMathError: [ " << e.what() << " ] " << endl ;
 640         status = false ;
 641     }
 642 
 643     fout_ << "\nTEST:  BigInt u -= static_cast<ppuint>(5) underflow" ;
 644     {
 645         try
 646         {
 647             BigInt u( "4" ) ;
 648             ppuint d = static_cast<ppuint>(5u) ;
 649             u -= d ;
 650 
 651             fout_ << ".........FAIL!" << endl ;
 652             fout_ << "    u = " ; printNumber( u, fout_ ) ; fout_ << endl ;
 653             fout_ << "    d = " << d << endl ;
 654             status = false ;
 655         }
 656         catch( BigIntUnderflow & e )
 657         {
 658            // Caught underflow;  works correctly.
 659            // fout_ << "Underflow: " << e.what() << endl ;
 660             fout_ << ".........PASS!" ;
 661         }
 662         catch( ... )
 663         {
 664             fout_ << ".........FAIL!" << endl ;
 665             fout_ << "    Didn't catch a BigIntUnderflow exception" << endl ;
 666             status = false ;
 667         }
 668     }
 669 
 670     fout_ << "\nTEST:  BigInt u += ppuint d" ;
 671     {
 672         BigInt u( "9994" ) ;
 673         ppuint d = static_cast<ppuint>(6u) ;
 674         u += d ;
 675         if (getNumDigits( u ) != 5 ||
 676             getDigit( u, 4 )  != 1 ||
 677             getDigit( u, 3 )  != 0 || getDigit( u, 2 ) != 0 ||
 678             getDigit( u, 1 )  != 0 || getDigit( u, 0 ) != 0
 679            )
 680         {
 681             fout_ << ".........FAIL!" << endl ;
 682             fout_ << "    u = " ; printNumber( u, fout_ ) ; fout_ << endl ;
 683             fout_ << "    d = " << d << endl ;
 684             status = false ;
 685         }
 686         else
 687             fout_ << ".........PASS!" ;
 688     }
 689 
 690     fout_ << "\nTEST:  BigInt v = BigInt u * ppuint d" ;
 691     {
 692         BigInt u( "123" ) ;
 693         ppuint d{ 4 } ;
 694         BigInt v = u * d ;
 695 
 696         if (getNumDigits( v ) != 3 ||
 697             getDigit( v, 2 ) != 4 ||
 698             getDigit( v, 1 ) != 9 || getDigit( v, 0 ) != 2
 699            )
 700         {
 701             fout_ << ".........FAIL!" << endl ;
 702             fout_ << "    u = " ; printNumber( u, fout_ ) ; fout_ << endl ;
 703             fout_ << "    v = " ; printNumber( v, fout_ ) ; fout_ << endl ;
 704             fout_ << "    d = " << d << endl ;
 705             status = false ;
 706         }
 707         else
 708             fout_ << ".........PASS!" ;
 709     }
 710 
 711     fout_ << "\nTEST:  BigInt u /= ppuint d" ;
 712     {
 713         BigInt u( "12" ) ;
 714         ppuint d{ 4 } ;
 715         u /= d ;
 716 
 717         if (getNumDigits( u ) != 1 || getDigit( u, 0 ) != 3)
 718         {
 719             fout_ << ".........FAIL!" << endl ;
 720             fout_ << "    u = " ; printNumber( u, fout_ ) ; fout_ << endl ;
 721             fout_ << "    d = " << d << endl ;
 722             status = false ;
 723         }
 724         else
 725             fout_ << ".........PASS!" ;
 726     }
 727 
 728     fout_ << "\nTEST:  BigInt u /= ppuint d underflow to zero." ;
 729     {
 730         BigInt u( "3" ) ;
 731         ppuint d{ 4 } ;
 732         u /= d ;
 733 
 734         if (getNumDigits( u ) != 1 || getDigit( u, 0 ) != 0)
 735         {
 736             fout_ << ".........FAIL!" << endl ;
 737             fout_ << "    u = " ; printNumber( u, fout_ ) ; fout_ << endl ;
 738             fout_ << "    d = " << d << endl ;
 739             status = false ;
 740         }
 741         else
 742             fout_ << ".........PASS!" ;
 743     }
 744 
 745     fout_ << "\nTEST:  BigInt v = ++BigInt u" ;
 746     {
 747         BigInt u( "123" ) ;
 748         BigInt v = ++u ;
 749 
 750         if (getNumDigits( u ) != 3 || getDigit( u, 2 ) != 1 || getDigit( u, 1 )  != 2 || getDigit( u, 0 ) != 4
 751            || (u != v))
 752         {
 753             fout_ << ".........FAIL!" << endl ;
 754             fout_ << "    u = " ; printNumber( u, fout_ ) ; fout_ << endl ;
 755             fout_ << "    v = " ; printNumber( v, fout_ ) ; fout_ << endl ;
 756             status = false ;
 757         }
 758         else
 759             fout_ << ".........PASS!" ;
 760     }
 761 
 762     fout_ << "\nTEST:  BigInt v = --BigInt u" ;
 763     {
 764         BigInt u( "123" ) ;
 765         BigInt v = --u ;
 766 
 767         if (getNumDigits( u ) != 3 ||
 768             getDigit( u, 2 ) != 1 || getDigit( u, 1 )  != 2 || getDigit( u, 0 ) != 2 ||
 769             (u != v))
 770         {
 771             fout_ << ".........FAIL!" << endl ;
 772             fout_ << "    u = " ; printNumber( u, fout_ ) ; fout_ << endl ;
 773             fout_ << "    v = " ; printNumber( v, fout_ ) ; fout_ << endl ;
 774             status = false ;
 775         }
 776         else
 777             fout_ << ".........PASS!" ;
 778     }
 779 
 780     fout_ << "\nTEST:  BigInt++" ;
 781     {
 782         BigInt u( "123" ) ;
 783         BigInt v = u++ ;
 784 
 785         if (getNumDigits( u ) != 3 ||
 786             getDigit( u, 2 ) != 1 || getDigit( u, 1 )  != 2 || getDigit( u, 0 ) != 4
 787            )
 788         {
 789             fout_ << ".........FAIL!" << endl ;
 790             fout_ << "    ++BigInt failed." << endl ;
 791             printNumber( u, fout_ ) ;
 792             status = false ;
 793         }
 794         else if (getNumDigits( v ) != 3 ||
 795             getDigit( v, 2 ) != 1 || getDigit( v, 1 )  != 2 || getDigit( v, 0 ) != 3
 796            )
 797         {
 798             fout_ << ".........FAIL!" << endl ;
 799             fout_ << "    BigInt++ failed." << endl ;
 800             printNumber( u, fout_ ) ;
 801             status = false ;
 802         }
 803         else
 804             fout_ << ".........PASS!" ;
 805     }
 806 
 807     fout_ << "\nTEST:  BigInt--" ;
 808     {
 809         BigInt u( "123" ) ;
 810         BigInt v = u-- ;
 811 
 812         if (getNumDigits( u ) != 3 ||
 813             getDigit( u, 2 ) != 1 || getDigit( u, 1 )  != 2 || getDigit( u, 0 ) != 2
 814            )
 815         {
 816             fout_ << "\n\tERROR:  BigInt-- failed." << endl ;
 817             printNumber( u, fout_ ) ;
 818             status = false ;
 819         }
 820         else if (getNumDigits( v ) != 3 ||
 821             getDigit( v, 2 ) != 1 || getDigit( v, 1 )  != 2 || getDigit( v, 0 ) != 3
 822            )
 823         {
 824             fout_ << "\n\tERROR:  BigInt-- failed." << endl ;
 825             printNumber( u, fout_ ) ;
 826             status = false ;
 827         }
 828         else
 829             fout_ << ".........PASS!" ;
 830     }
 831 
 832     fout_ << "\nTEST:  one digit BigInt + ppuint" ;
 833     {
 834         BigInt u( "3" ) ;
 835         ppuint d{ 4 } ;
 836         BigInt w = u + d ;
 837 
 838         if (getNumDigits( w ) != 1 || getDigit( w, 0 ) != 7)
 839         {
 840             fout_ << "\n\tERROR:  BigInt + BigInt 3 + 4 = 7 failed." << endl ;
 841             printNumber( w, fout_ ) ;
 842             status = false ;
 843         }
 844         else
 845             fout_ << ".........PASS!" ;
 846     }
 847 
 848     fout_ << "\nTEST:  two digit BigInt + ppuint" ;
 849     {
 850         BigInt u( "3" ) ;
 851         ppuint d{ 9 } ;
 852         BigInt w = u + d ;
 853 
 854         if (getNumDigits( w ) != 2 || getDigit( w, 1 ) != 1
 855                                    || getDigit( w, 0 ) != 2)
 856         {
 857             fout_ << "\n\tERROR:  BigInt + BigInt 3 + 9 = 12 failed." << endl ;
 858             printNumber( w, fout_ ) ;
 859             status = false ;
 860         }
 861         else
 862             fout_ << ".........PASS!" ;
 863     }
 864 
 865     fout_ << "\nTEST:  BigInt + BigInt" ;
 866     {
 867         BigInt u( "9999" ) ;
 868         BigInt v(  "999" ) ;
 869         BigInt w = u + v ;
 870 
 871         if (getNumDigits( w ) != 5 || getDigit( w, 4 ) != 1
 872                                    || getDigit( w, 3 ) != 0
 873                                    || getDigit( w, 2 ) != 9
 874                                    || getDigit( w, 1 ) != 9
 875                                    || getDigit( w, 0 ) != 8)
 876         {
 877             fout_ << "\n\tERROR:  BigInt + BigInt 9999 + 999 = 10998 failed." << endl ;
 878             printNumber( w, fout_ ) ;
 879             status = false ;
 880         }
 881         else
 882             fout_ << ".........PASS!" ;
 883     }
 884 
 885     fout_ << "\nTEST:  BigInt + BigInt" ;
 886     {
 887         BigInt u(  "999" ) ;
 888         BigInt v( "9999" ) ;
 889         BigInt w = u + v ;
 890 
 891         if (getNumDigits( w ) != 5 || getDigit( w, 4 ) != 1
 892                                    || getDigit( w, 3 ) != 0
 893                                    || getDigit( w, 2 ) != 9
 894                                    || getDigit( w, 1 ) != 9
 895                                    || getDigit( w, 0 ) != 8)
 896         {
 897             fout_ << "\n\tERROR:  BigInt + BigInt 999 + 9999 = 10998 failed." << endl ;
 898             printNumber( w, fout_ ) ;
 899             status = false ;
 900         }
 901         else
 902             fout_ << ".........PASS!" ;
 903     }
 904 
 905     fout_ << "\nTEST:  BigInt - BigInt" ;
 906     {
 907         BigInt u( "103" ) ;
 908         BigInt v(   "9" ) ;
 909         BigInt w = u - v ;
 910 
 911         if (getNumDigits( w ) != 2 || getDigit( w, 1 ) != 9
 912                                    || getDigit( w, 0 ) != 4)
 913         {
 914             fout_ << "\n\tERROR:  BigInt - BigInt 103 - 9 = 94 failed." << endl ;
 915             printNumber( w, fout_ ) ;
 916             status = false ;
 917         }
 918         else
 919             fout_ << ".........PASS!" ;
 920     }
 921 
 922     fout_ << "\nTEST:  BigInt - BigInt < 0" ;
 923     try
 924     {
 925         BigInt u( "9" ) ;
 926         BigInt v( "103" ) ;
 927         BigInt w = u - v ;
 928 
 929         fout_ << "\n\tERROR:  BigInt - BigInt 9 - 103 failed didn't catch range exception." << endl ;
 930         printNumber( w, fout_ ) ;
 931         status = false ;
 932     }
 933     catch( BigIntUnderflow & e )
 934     {
 935         // Caught underflow;  works correctly.
 936         // fout_ << "Underflow: " << e.what() << endl ;
 937         fout_ << ".........PASS!" ;
 938     }
 939 
 940     fout_ << "\nTEST:  BigInt - ppuint" ;
 941     {
 942         BigInt u( "103" ) ;
 943         ppuint d{ 9 } ;
 944         BigInt w = u - d ;
 945 
 946         if (getNumDigits( w ) != 2 || getDigit( w, 1 ) != 9
 947                                    || getDigit( w, 0 ) != 4)
 948         {
 949             fout_ << "\n\tERROR:  BigInt - ppuint 103 - 9 = 94 failed." << endl ;
 950             printNumber( w, fout_ ) ;
 951             status = false ;
 952         }
 953         else
 954             fout_ << ".........PASS!" ;
 955     }
 956 
 957     fout_ << "\nTEST:  one digit BigInt * BigInt" ;
 958     {
 959         BigInt u( "3" ) ;
 960         BigInt v( "3" ) ;
 961         BigInt w = u * v ;
 962 
 963         if (getNumDigits( w ) != 1 || getDigit( w, 0 ) != 9)
 964         {
 965             fout_ << "\n\tERROR:  BigInt * BigInt 3 * 3 = 9 failed." << endl ;
 966             printNumber( w, fout_ ) ;
 967             status = false ;
 968         }
 969         else
 970             fout_ << ".........PASS!" ;
 971     }
 972 
 973     fout_ << "\nTEST:  two digit BigInt * BigInt" ;
 974     {
 975         BigInt u( "3" ) ;
 976         BigInt v( "4" ) ;
 977         BigInt w = u * v ;
 978 
 979         if (getNumDigits( w ) != 2 || getDigit( w, 1 ) != 1 || getDigit( w, 0 ) != 2)
 980         {
 981             fout_ << "\n\tERROR:  BigInt * BigInt = 3 * 4 = 12 failed." << endl ;
 982             printNumber( w, fout_ ) ;
 983             status = false ;
 984         }
 985         else
 986             fout_ << ".........PASS!" ;
 987     }
 988 
 989     fout_ << "\nTEST:  BigInt multidigit *" ;
 990     {
 991         BigInt w ;
 992         BigInt u( "329218104" ) ;
 993         BigInt v(      "3606" ) ;
 994 
 995         w = u * v ;
 996 
 997         string s = w.toString() ;
 998 
 999         if (s != "1187160483024" )
1000         {
1001             fout_ << "\n\tERROR:  BigInt multidigit * failed." << endl ;
1002             fout_ << "u = " ; printNumber( u, fout_ ) ;
1003             fout_ << "v = " ; printNumber( v, fout_ ) ;
1004             fout_ << "w = " ; printNumber( w, fout_ ) ;
1005             status = false ;
1006         }
1007         else
1008         {
1009             fout_ << ".........PASS!" ;
1010         }
1011     }
1012 
1013     fout_ << "\nTEST:  BigInt multidigit *=" ;
1014     {
1015         BigInt u( "329218104" ) ;
1016         BigInt v(      "3606" ) ;
1017 
1018         u *= v ;
1019 
1020         string s = u.toString() ;
1021 
1022         if (s != "1187160483024" )
1023         {
1024             fout_ << "\n\tERROR:  BigInt multidigit *= failed." << endl ;
1025             fout_ << "u = " ; printNumber( u, fout_ ) ;
1026             fout_ << "v = " ; printNumber( v, fout_ ) ;
1027             status = false ;
1028         }
1029         else
1030         {
1031             fout_ << ".........PASS!" ;
1032         }
1033     }
1034 
1035     fout_ << "\nTEST:  BigInt / BigInt one digit divisor." ;
1036     {
1037         BigInt u( "12" ) ;
1038         BigInt v( "4" ) ;
1039         BigInt w = u / v ;
1040 
1041         if (getNumDigits( w ) != 1 || getDigit( w, 0 ) != 3)
1042         {
1043             fout_ << "\n\tERROR:  BigInt / BigInt = 12/4 = 3 failed." << endl ;
1044             printNumber( w, fout_ ) ;
1045             status = false ;
1046         }
1047         else
1048             fout_ << ".........PASS!" ;
1049     }
1050 
1051     fout_ << "\nTEST:  BigInt / BigInt multidigit" ;
1052     {
1053         BigInt u( "398765" ) ;
1054         BigInt v( "3457" ) ;
1055         BigInt w = u / v ;
1056 
1057         if (getNumDigits( w ) != 3 ||
1058                 getDigit( w, 2 ) != 1 || getDigit( w, 1 ) != 1 || getDigit( w, 0 ) != 5)
1059         {
1060             fout_ << "\n\tERROR:  BigInt / BigInt = 398765/3457 = 215 failed." << endl ;
1061             printNumber( w, fout_ ) ;
1062             status = false ;
1063         }
1064         else
1065             fout_ << ".........PASS!" ;
1066     }
1067 
1068     fout_ << "\nTEST:  BigInt / BigInt leading zero digit." ;
1069     {
1070         BigInt u( "120" ) ;
1071         BigInt v( "40" ) ;
1072         BigInt w = u / v ;
1073 
1074         if (getNumDigits( w ) != 1 || getDigit( w, 0 ) != 3)
1075         {
1076             fout_ << "\n\tERROR:  BigInt / BigInt = 120/40 = 3 failed." << endl ;
1077             printNumber( w, fout_ ) ;
1078             status = false ;
1079         }
1080         else
1081             fout_ << ".........PASS!" ;
1082     }
1083 
1084     fout_ << "\nTEST:  BigInt / 0 " ;
1085     try
1086     {
1087         BigInt u( "120" ) ;
1088         BigInt v( "0" ) ;
1089         BigInt w = u / v ;
1090 
1091         fout_ << "\n\tERROR:  BigInt / 0 = 120/0 failed." << endl ;
1092         status = false ;
1093     }
1094     catch( BigIntZeroDivide & e )
1095     {
1096         // Should catch zero divide here.
1097         fout_ << ".........PASS!" ;
1098     }
1099 
1100     fout_ << "\nTEST:  BigInt % BigInt with u > v" ;
1101     {
1102         BigInt u( "398765" ) ;
1103         BigInt v( "3457" ) ;
1104         BigInt r = u % v ;
1105 
1106         if (getNumDigits( r ) != 4 ||
1107                 getDigit( r, 3 ) != 1 || getDigit( r, 2 ) != 2 ||
1108                 getDigit( r, 1 ) != 1 || getDigit( r, 0 ) != 0)
1109         {
1110             fout_ << "\n\tERROR:  BigInt % BigInt = 398765 / 3457 = 1210 failed." << endl ;
1111             printNumber( r, fout_ ) ;
1112             status = false ;
1113         }
1114         else
1115         {
1116             fout_ << ".........PASS!" ;
1117         }
1118     }
1119 
1120     fout_ << "\nTEST:  BigInt multidigit mod with normalizing constant d = 1" ;
1121     {
1122         BigInt w ;
1123         BigInt u( "1369244731822264511994463394" ) ;
1124         BigInt v(  "954901783703457032047844259" ) ;
1125 
1126         w = u % v ;
1127 
1128         string s{ w.toString() } ;
1129 
1130         if (s != "414342948118807479946619135" )
1131         {
1132             fout_ << "\n\tERROR:  BigInt multidigit mod failed." << endl ;
1133             fout_ << "u = " ; printNumber( u, fout_ ) ;
1134             fout_ << "v = " ; printNumber( v, fout_ ) ;
1135             fout_ << "w = " ; printNumber( w, fout_ ) ;
1136             status = false ;
1137         }
1138         else
1139         {
1140             fout_ << ".........PASS!" ;
1141         }
1142     }
1143 
1144     fout_ << "\nTEST:  BigInt % BigInt with u < v" ;
1145     {
1146         BigInt u( "12" ) ;
1147         BigInt v( "34567" ) ;
1148         BigInt r{ u % v } ;
1149 
1150         if (getNumDigits( r ) != 2 ||
1151             getDigit( r, 1 ) != 1 || getDigit( r, 0 ) != 2)
1152         {
1153             fout_ << "\n\tERROR:  BigInt % BigInt = 12 mod 345 = 12 failed." << endl ;
1154             printNumber( r, fout_ ) ;
1155             status = false ;
1156         }
1157         else
1158             fout_ << ".........PASS!" ;
1159     }
1160 
1161     fout_ << "\nTEST:  BigInt % ppuint = 314159 / 9 = 5 with ppuint < base " ;
1162     {
1163         BigInt u( "314159" ) ;
1164         ppuint v{ 9u } ;
1165         ppuint r{ u % v } ;
1166 
1167         if (r != 5)
1168         {
1169             fout_ << "\n\tERROR:  [BigInt u % ppuint v = r]:  314159 / 9 = 5 failed" << endl ;
1170             fout_ << "u = " << u << " v = " << v << " r = " << r << " for base = " << BigInt::getBase() << endl ;
1171             status = false ;
1172         }
1173         else
1174             fout_ << ".........PASS!" ;
1175     }
1176 
1177     fout_ << "\nTEST:  BigInt % ppuint = 398765 % 11u with ppuint > base = 10 throws error? " ;
1178     try
1179     {
1180         BigInt u( "398765" ) ;
1181         ppuint v{ 11u } ;
1182         ppuint r{ u % v } ;
1183 
1184         fout_ << "\n\tERROR:  BigInt % ppuint = 398765 % 11 = 4 failed for base = " << BigInt::getBase() << endl ;
1185         fout_ << "\n\tERROR:  [BigInt u % ppuint v = r]:  398765 / 11 = 4 failed" << endl ;
1186         fout_ << "u = " << u << " v = " << v << " r = " << r << " for base = " << BigInt::getBase() << endl ;
1187         status = false ;
1188     }
1189     catch( BigIntOverflow & e )
1190     {
1191         fout_ << ".........PASS!" ;
1192     }
1193 
1194     fout_ << "\nTEST:  BigInt / BigInt low probability if branch." ;
1195     {
1196         BigInt u( "4100" ) ;
1197         BigInt v( "588" ) ;
1198         BigInt w{ u / v } ;
1199 
1200         if (w != BigInt("6"))
1201             fout_ << "error" << endl;
1202 
1203         if (getNumDigits( w ) != 1 || getDigit( w, 0 ) != 6)
1204         {
1205             fout_ << "\n\tERROR:  BigInt / BigInt = 4100/588 = 6 failed." << endl ;
1206             printNumber( w, fout_ ) ;
1207             status = false ;
1208         }
1209         else
1210             fout_ << ".........PASS!" ;
1211     }
1212 
1213     fout_ << "\nTEST:  Switching back from base " << 10 << " to oldBase " << oldBase ;
1214     BigInt dummy ;
1215     setBase( dummy, oldBase ) ;
1216     if (BigInt::getBase() != oldBase)
1217     {
1218         fout_ << "\n\tERROR: Changing back to default base for all BigInt objects "
1219              << "       failed.  base = " << BigInt::getBase() << endl ;
1220         status = false ;
1221     }
1222     else
1223         fout_ << ".........PASS!" ;
1224 
1225     return status ;
1226 }
1227 
1228 
1229 
1230 bool UnitTest::unitTestBigIntDefaultBase()
1231 {
1232     bool status{ true } ;
1233 
1234     fout_ << "\nTEST:  Decimal string to BigInt conversion and back to decimal string using default base." ;
1235     {
1236         BigInt x( "3141592653589793238462643383279" ) ;
1237         string s{ x.toString() } ;
1238 
1239         if (s != "3141592653589793238462643383279" )
1240         {
1241             fout_ << "\n\tERROR:  BigInt default base conversion failed." << endl ;
1242             fout_ << "x = " << x << " " ; printNumber( x, fout_ ) ;
1243             fout_ << " NOT EQUAL TO s = 3141592653589793238462643383279 (decimal digits)" << endl ;
1244             status = false ;
1245         }
1246         else
1247             fout_ << ".........PASS!" ;
1248     }
1249 
1250     fout_ << "\nTEST:  BigInt z = x * y then x =? z / y multidigit with default base." ;
1251     {
1252         BigInt x( "3141592653589793238462643383279" ) ;
1253         BigInt y( "2718281828459045" ) ;
1254         BigInt z{ x * y } ;
1255         BigInt w{ z / y } ;
1256 
1257         if (w != x)
1258         {
1259             fout_ << "\n\tERROR:  BigInt z = x * y then x =? z / y multidigit with default base failed." << endl ;
1260             fout_ << "x = " ; printNumber( x, fout_ ) ;
1261             fout_ << "y = " ; printNumber( y, fout_ ) ;
1262             fout_ << "z = " ; printNumber( z, fout_ ) ;
1263             fout_ << "w = " ; printNumber( w, fout_ ) ;
1264             status = false ;
1265         }
1266         else
1267             fout_ << ".........PASS!" ;
1268     }
1269 
1270     fout_ << "\nTEST:  BigInt testBit" ;
1271     {
1272         BigInt u( "31415926535897932" ) ;
1273 
1274         if (u.testBit( 0 ) == false  &&
1275             u.testBit( 1 ) == false  &&
1276             u.testBit( 2 ) == true   &&
1277             u.testBit( 3 ) == true   &&
1278             u.testBit( 4 ) == false  &&
1279             u.testBit( 5 ) == false  &&
1280             u.testBit( 6 ) == true   &&
1281             u.testBit( 7 ) == false)
1282         {
1283             fout_ << ".........PASS!" ;
1284         }
1285         else
1286         {
1287             fout_ << "\n\tERROR:  BigInt testBit failed." << endl ;
1288             printNumber( u, fout_ ) ;
1289             fout_ << "testBit 0 = " << (u.testBit( 0 ) == true) << endl ;
1290             fout_ << "testBit 1 = " << (u.testBit( 1 ) == true) << endl ;
1291             fout_ << "testBit 2 = " << (u.testBit( 2 ) == true) << endl ;
1292             fout_ << "testBit 3 = " << (u.testBit( 3 ) == true) << endl ;
1293             fout_ << "testBit 4 = " << (u.testBit( 4 ) == true) << endl ;
1294             fout_ << "testBit 5 = " << (u.testBit( 5 ) == true) << endl ;
1295             fout_ << "testBit 6 = " << (u.testBit( 6 ) == true) << endl ;
1296             fout_ << "testBit 7 = " << (u.testBit( 7 ) == true) << endl ;
1297             status = false ;
1298         }
1299     }
1300 
1301     fout_ << "\nTEST:  testBit()" ;
1302     {
1303         ppuint u{ 0b100101 } ; // Set bits 0, 2 and 5 using C++14 binary literals.
1304 
1305         if (testBit( u, 0 ) == true   &&
1306             testBit( u, 1 ) == false  &&
1307             testBit( u, 2 ) == true   &&
1308             testBit( u, 3 ) == false  &&
1309             testBit( u, 4 ) == false  &&
1310             testBit( u, 5 ) == true   &&
1311             testBit( u, 6 ) == false  &&
1312             testBit( u, 7 ) == false)
1313         {
1314             fout_ << ".........PASS!" ;
1315         }
1316         else
1317         {
1318             fout_ << "\n\tERROR:  ppuint testBit failed for u = " << u << endl ;
1319             fout_ << "testBit 0 = " << (testBit( u, 0 ) == true) << endl ;
1320             fout_ << "testBit 1 = " << (testBit( u, 1 ) == true) << endl ;
1321             fout_ << "testBit 2 = " << (testBit( u, 2 ) == true) << endl ;
1322             fout_ << "testBit 3 = " << (testBit( u, 3 ) == true) << endl ;
1323             fout_ << "testBit 4 = " << (testBit( u, 4 ) == true) << endl ;
1324             fout_ << "testBit 5 = " << (testBit( u, 5 ) == true) << endl ;
1325             fout_ << "testBit 6 = " << (testBit( u, 6 ) == true) << endl ;
1326             fout_ << "testBit 7 = " << (testBit( u, 7 ) == true) << endl ;
1327             status = false ;
1328         }
1329     }
1330 
1331     fout_ << "\nTEST:  BigInt power( ppuint 2, ppuint 100 )" ;
1332     {
1333         ppuint p{ 2u } ;
1334         int n{ 100 } ;
1335         BigInt u{ power( p, n ) } ;
1336         string s{ u.toString() } ;
1337 
1338         BigInt v{ 1u } ;
1339         for (int i = 1 ; i <= n ; ++i)
1340             v *= p ;
1341         string sv{ v.toString() } ;
1342 
1343         if (s != sv)
1344         {
1345             fout_ << "\n\tERROR:  BigInt power( 2, 100 ) = " << u << endl ;
1346             fout_ << "correct answer = " << v << endl ;
1347             status = false ;
1348         }
1349         else
1350             fout_ << ".........PASS!" ;
1351     }
1352 
1353     fout_ << "\nTEST:  BigInt ceilLg( 6 )" ;
1354     {
1355         BigInt u{ 6u } ;
1356 
1357         int ceilingOfLog2 = u.ceilLg() ;
1358         if (ceilingOfLog2 != 3)
1359         {
1360             fout_ << "\n\tERROR:  BigInt ceilingOfLog2( 6 ) = " << ceilingOfLog2 << endl ;
1361             fout_ << "correct answer = 3" << endl ;
1362             status = false ;
1363         }
1364         else
1365             fout_ << ".........PASS!" ;
1366     }
1367 
1368     fout_ << "\nTEST:  BigInt eval 2 ^ 1198 - 1" ;
1369     {
1370         BigInt largePowerOf2Minus1 = power( 2, 1198 ) - static_cast< BigInt >( 1u ) ;
1371         /// cout << "largePowerOf2Minus1 = " << largePowerOf2Minus1 << endl ;
1372         BigInt f1{ BigInt( 3u ) } ;
1373         BigInt f2{ BigInt( "366994123" ) } ;
1374         BigInt f3{ BigInt( "16659379034607403556537" ) } ;
1375         BigInt f4{ BigInt( "148296291984475077955727317447564721950969097" ) } ;
1376         BigInt f5{ BigInt( "839804700900123195473468092497901750422530587828620063507554515144683510250490874819119570309824866293030799718783" ) } ;
1377         BigInt f6{ BigInt( "188446049896780543200161267236930710150747483597643192594833338774867012035362945326134784314021280857050576738677"
1378             "1290423087216156597588216186445958479269565424431335013281" ) } ;
1379         BigInt product{ f1 * f2 * f3 * f4 * f5 * f6 } ;
1380         bool allFactorsPrime{ isAlmostSurelyPrime( f1 ) && isAlmostSurelyPrime( f2 ) && isAlmostSurelyPrime( f3 ) &&
1381                               isAlmostSurelyPrime( f4 ) && isAlmostSurelyPrime( f5 ) && isAlmostSurelyPrime( f6 ) } ;
1382         /// cout << "all factors prime = " << allFactorsPrime << endl ;
1383         /// cout << "product = " << product << endl ;
1384 
1385         if (product != largePowerOf2Minus1 || !allFactorsPrime)
1386         {
1387             fout_ << "\nERROR:  BigInt eval 2 ^ 1198 - 1 != 3 * 366994123 * 16659379034607403556537 * 148296291984475077955727317447564721950969097 * "
1388             "839804700900123195473468092497901750422530587828620063507554515144683510250490874819119570309824866293030799718783 * "
1389             "18844604989678054320016126723693071015074748359764319259483333877486701203536294532613478431402128085705057673867712"
1390             "90423087216156597588216186445958479269565424431335013281" << endl ;
1391             status = false ;
1392         }
1393         else
1394             fout_ << ".........PASS!" ;
1395     }
1396 
1397     return status ;
1398 }
1399 
1400 
1401 bool UnitTest::unitTestModPArithmetic()
1402 {
1403     volatile bool status{ true } ; // Suppress XCode warning about Dead store: value never read.
1404 
1405     fout_ << "\nTEST:  ModP 10 = 3 (mod 7)" ;
1406     {
1407         ModP<ppuint,ppsint> modp( 7 ) ;
1408         if (modp( 10 ) != 3)
1409         {
1410             fout_ << ".........FAIL!" << endl ;
1411             fout_ << "    ModP modp( 7 );  modp( 10 ) = " << modp( 10 ) << endl ;
1412             status = false ;
1413         }
1414         else
1415             fout_ << ".........PASS!" ;
1416     }
1417 
1418     fout_ << "\nTEST:  ModP -10 = 4 (mod 7)" ;
1419     {
1420         ModP<ppuint,ppsint> modp( 7 ) ;
1421         if (modp( -10 ) != 4)
1422         {
1423             fout_ << ".........FAIL!" << endl ;
1424             fout_ << "    ModP modp( 7 );  modp( -10 ) = " << modp( -10 ) << endl ;
1425             ppsint n = -10 ;
1426             ppsint p = 7 ;
1427             fout_ << "+ + + + + + + +" << endl ;
1428             fout_ <<   n << endl ;
1429             fout_ <<   p << endl ;
1430             fout_ <<   (n % p) << endl ;
1431             fout_ << ( (n % p) + p ) << endl ;
1432             fout_ << "+ + + + + + + +" << endl ;
1433             status = false ;
1434         }
1435         else
1436             fout_ << ".........PASS!" ;
1437     }
1438 
1439     fout_ << "\nTEST:  ModP( 0 ) throwing ArithModPError" ;
1440     {
1441         try
1442         {
1443             ModP<ppuint,ppsint> modp( 0 ) ;
1444             modp( 10 ) ;
1445 
1446             status = false ;
1447             fout_ << ".........FAIL!\n    did not catch ArithModPError when p <= 0" << endl ;
1448         }
1449         catch( ArithModPError & e )
1450         {
1451             // Since we cannot debug trace exceptions in XCode, break on this statement so we can see it works OK.
1452             fout_ << ".........PASS!" ;
1453         }
1454     }
1455 
1456     fout_ << "\nTEST:  ppuint gcd( 85, 25 ) = 5" ;
1457     {
1458         ppuint u{ 85u } ;
1459         ppuint v{ 25u } ;
1460         ppuint g{ gcd( u, v ) } ;
1461         if (g != static_cast<ppuint>(5u))
1462         {
1463             fout_ << ".........FAIL!" << endl ;
1464             fout_ << "    ppuint gcd( 85, 25 ) = " << g << endl ;
1465             status = false ;
1466         }
1467         else
1468             fout_ << ".........PASS!" ;
1469     }
1470 
1471     fout_ << "\nTEST:  BigInt gcd( 779953197883173551166308319545, 1282866356929526866866376009397 ) = 1" ;
1472     {
1473         BigInt u( "779953197883173551166308319545" ) ;
1474         BigInt v( "1282866356929526866866376009397" ) ;
1475         BigInt g = gcd( u, v ) ;
1476         if (g != static_cast<BigInt>( static_cast<ppuint>(1u) ))
1477         {
1478             fout_ << ".........FAIL!" << endl ;
1479             fout_ << "    BigInt gcd = " << g << endl ;
1480             status = false ;
1481         }
1482         else
1483             fout_ << ".........PASS!" ;
1484     }
1485 
1486     fout_ << "\nTEST:  c,r = addMod( a, b, n ) for ppuint type " ;
1487     {
1488         if (8 * sizeof( ppuint ) == 64)
1489         {
1490             fout_ << "of 64 bits " ;
1491             ppuint a = static_cast<ppuint>(18446744073709551614ULL) ; // 2^64-1-1
1492             ppuint b = static_cast<ppuint>(18446744073709551615ULL) ; // 2^64-1
1493             ppuint n = static_cast<ppuint>(18446744073709551615ULL) ; // 2^64-1
1494             ppuint c = static_cast<ppuint>(18446744073709551614ULL) ; // 2^64-1-1
1495             ppuint r = addMod( a, b, n ) ;
1496             if (r != c)
1497             {
1498                 fout_ << ".........FAIL!" << endl ;
1499                 fout_ << "a = " << a << endl ;
1500                 fout_ << "b = " << b << endl ;
1501                 fout_ << "n = " << n << endl ;
1502                 fout_ << "c = " << c << endl ;
1503                 fout_ << "r = " << r << endl ;
1504                 status = false ;
1505             }
1506             else
1507                 fout_ << ".........PASS!" ;
1508         }
1509         else if (8 * sizeof( ppuint ) == 32)
1510         {
1511             fout_ << "of 32 bits " ;
1512             ppuint a{ static_cast<ppuint>(4294967295u) } ; // 2^32-1
1513             ppuint b{ static_cast<ppuint>(4294967294u) } ; // (2^32-1)-1
1514             ppuint n{ static_cast<ppuint>(4294967295u) } ; // 2^32-1
1515             ppuint c{ static_cast<ppuint>(4294967294u) } ; // (2^32-1)-1
1516             ppuint r{ addMod( a, b, n ) } ;
1517             if (r != c)
1518             {
1519                 fout_ << ".........FAIL!" << endl ;
1520                 fout_ << "a = " << a << endl ;
1521                 fout_ << "b = " << b << endl ;
1522                 fout_ << "n = " << n << endl ;
1523                 fout_ << "c = " << c << endl ;
1524                 fout_ << "r = " << r << endl ;
1525                 status = false ;
1526             }
1527             else
1528                 fout_ << ".........PASS!" ;
1529         }
1530     }
1531 
1532     fout_ << "\nTEST:  c,r = timesTwoMod( a, n ) for ppuint type " ;
1533     {
1534         if (8 * sizeof( ppuint ) == 64)
1535         {
1536             fout_ << "of 64 bits " ;
1537             ppuint a = static_cast<ppuint>(18446744073709551614ULL) ; // 2^64-1-1
1538             ppuint n = static_cast<ppuint>(18446744073709551615ULL) ; // 2^64-1
1539             ppuint c = static_cast<ppuint>(18446744073709551613ULL) ; // 2^64-1-2
1540             ppuint r = timesTwoMod( a, n ) ;
1541             if (r != c)
1542             {
1543                 fout_ << ".........FAIL!" << endl ;
1544                 fout_ << "a = " << a << endl ;
1545                 fout_ << "n = " << n << endl ;
1546                 fout_ << "c = " << c << endl ;
1547                 fout_ << "r = " << r << endl ;
1548                 status = false ;
1549             }
1550             else
1551                 fout_ << ".........PASS!" ;
1552         }
1553         else if (8 * sizeof( ppuint ) == 32)
1554         {
1555             fout_ << "of 32 bits " ;
1556             ppuint a{ static_cast<ppuint>(4294967294u) } ; // 2^32-1-1
1557             ppuint n{ static_cast<ppuint>(4294967295u) } ; // 2^32-1
1558             ppuint c{  static_cast<ppuint>(4294967293u) } ; // (2^32-1)-2
1559             ppuint r{ timesTwoMod( a, n ) } ;
1560             if (r != c)
1561             {
1562                 fout_ << ".........FAIL!" << endl ;
1563                 fout_ << "a = " << a << endl ;
1564                 fout_ << "n = " << n << endl ;
1565                 fout_ << "c = " << c << endl ;
1566                 fout_ << "r = " << r << endl ;
1567                 status = false ;
1568             }
1569             else
1570                 fout_ << ".........PASS!" ;
1571         }
1572     }
1573 
1574     fout_ << "\nTEST:  c,r = multiplyMod( a, b, n ) for ppuint type " ;
1575     {
1576         if (8 * sizeof( ppuint ) == 64)
1577         {
1578             fout_ << "of 64 bits " ;
1579             ppuint a{ static_cast<ppuint>(18446744073709551614ULL) } ; // 2^64-1-1
1580             ppuint b{ static_cast<ppuint>(18446744073709551614ULL) } ; // 2^64-1-1
1581             ppuint n{ static_cast<ppuint>(18446744073709551615ULL) } ; // 2^64-1
1582             ppuint c{ static_cast<ppuint>(1ULL) } ;                    // 1
1583             ppuint r{ multiplyMod( a, b, n ) } ;
1584             if (r != c)
1585             {
1586                 fout_ << ".........FAIL!" << endl ;
1587                 fout_ << "a = " << a << endl ;
1588                 fout_ << "b = " << b << endl ;
1589                 fout_ << "n = " << n << endl ;
1590                 fout_ << "c = " << c << endl ;
1591                 fout_ << "r = " << r << endl ;
1592                 status = false ;
1593             }
1594             else
1595                 fout_ << ".........PASS!" ;
1596         }
1597         else if (8 * sizeof( ppuint ) == 32)
1598         {
1599             fout_ << "of 32 bits " ;
1600             ppuint a{ static_cast<ppuint>(4294967294u) } ; // 2^32-1-1
1601             ppuint b{ static_cast<ppuint>(4294967294u) } ; // 2^32-1-1
1602             ppuint n{ static_cast<ppuint>(4294967295u) } ; // 2^32-1
1603             ppuint c{ static_cast<ppuint>(1u) } ; // 1
1604             ppuint r{ multiplyMod( a, b, n ) } ;
1605             if (r != c)
1606             {
1607                 fout_ << ".........FAIL!" << endl ;
1608                 fout_ << "a = " << a << endl ;
1609                 fout_ << "b = " << b << endl ;
1610                 fout_ << "n = " << n << endl ;
1611                 fout_ << "c = " << c << endl ;
1612                 fout_ << "r = " << r << endl ;
1613                 status = false ;
1614             }
1615             else
1616                 fout_ << ".........PASS!" ;
1617         }
1618     }
1619 
1620     fout_ << "\nTEST:  PowerMod ppuint 3^10 = 4 (mod 7)" ;
1621     {
1622         PowerMod<ppuint> powermod( static_cast<ppuint>(7u) ) ;
1623         if (powermod( static_cast<ppuint>(3u), static_cast<ppuint>(10u) ) != static_cast<ppuint>(4u))
1624         {
1625             fout_ << ".........FAIL!" << endl ;
1626             fout_ << "    PowerMod powermod( 7 );  powermod( 3, 10 ) = " << powermod( 3, 10 ) << " failed." << endl ;
1627             status = false ;
1628         }
1629         else
1630             fout_ << ".........PASS!" ;
1631     }
1632 
1633     fout_ << "\nTEST:  c,r = PowerMod( a, b ) modulo n for ppuint type " ;
1634     {
1635         if (8 * sizeof( ppuint ) == 64)
1636         {
1637             fout_ << "of 64 bits " ;
1638             ppuint a{ static_cast<ppuint>(2323123u) } ;
1639             ppuint b{ static_cast<ppuint>(10u) } ;
1640             ppuint n{ static_cast<ppuint>(18446744073709551615ULL) } ; // 2^64-1
1641             ppuint c{ static_cast<ppuint>(17955139022230052569ULL) } ;
1642             PowerMod<ppuint> powermod( n ) ;
1643             ppuint r = powermod( a, b ) ;
1644             if (r != c)
1645             {
1646                 fout_ << ".........FAIL!" << endl ;
1647                 fout_ << "a = " << a << endl ;
1648                 fout_ << "b = " << b << endl ;
1649                 fout_ << "n = " << n << endl ;
1650                 fout_ << "c = " << c << endl ;
1651                 fout_ << "r = " << r << endl ;
1652                 status = false ;
1653             }
1654             else
1655                 fout_ << ".........PASS!" ;
1656         }
1657         else if (8 * sizeof( ppuint ) == 32)
1658         {
1659             fout_ << "of 32 bits " ;
1660             ppuint a{ static_cast<ppuint>(4294967290u) } ;
1661             ppuint b{ static_cast<ppuint>(10u) } ;
1662             ppuint n{ static_cast<ppuint>(4294967295u) } ; // 2^32-1
1663             ppuint c{ static_cast<ppuint>(9765625u) } ;
1664             PowerMod<ppuint> powermod( n ) ;
1665             ppuint r{ powermod( a, b ) } ;
1666             if (r != c)
1667             {
1668                 fout_ << ".........FAIL!" << endl ;
1669                 fout_ << "a = " << a << endl ;
1670                 fout_ << "b = " << b << endl ;
1671                 fout_ << "n = " << n << endl ;
1672                 fout_ << "c = " << c << endl ;
1673                 fout_ << "r = " << r << endl ;
1674                 status = false ;
1675             }
1676             else
1677                 fout_ << ".........PASS!" ;
1678         }
1679     }
1680 
1681     fout_ << "\nTEST:  PowerMod BigInt 3^10 = 4 (mod 7)" ;
1682     PowerMod<BigInt> powermod( static_cast<BigInt>(static_cast<ppuint>(7u)) ) ;
1683     if (powermod( static_cast<BigInt>(static_cast<ppuint>(3u)),
1684                   static_cast<BigInt>(static_cast<ppuint>(10u)) ) != static_cast<BigInt>(static_cast<ppuint>(4u)))
1685     {
1686         BigInt three{ 3u } ;
1687         BigInt ten{ 10u } ;
1688         fout_ << "\n\tERROR:  PowerMod powermod( 7 );  powermod( 3, 10 ) = " << powermod( three, ten ) << " failed." << endl ;
1689         status = false ;
1690     }
1691     else
1692         fout_ << ".........PASS!" ;
1693 
1694     fout_ << "\nTEST:  PowerMod with out of range inputs." ;
1695     try
1696     {
1697         PowerMod<BigInt> powermod{ static_cast<BigInt>(static_cast<ppuint>( 7u )) } ;
1698         powermod( static_cast<BigInt>(static_cast<ppuint>( 0u )), static_cast<BigInt>(static_cast<ppuint>( 0u )) ) ;
1699 
1700         fout_ << "\n\tERROR:  PowerMod on 0^0 didn't throw exception." << endl ;
1701         status = false ;
1702     }
1703     catch( ArithModPError & e )
1704     {
1705         fout_ << ".........PASS!" ;
1706     }
1707 
1708     fout_ << "\nTEST:  InverseModP 3 * 5 = 1 (mod 7)" ;
1709     InverseModP imodp( 7 ) ;
1710     if (imodp( 3 ) != 5)
1711     {
1712         fout_ << "\n\tERROR:  InverseModP imodp( 7 );  imodp( 3 ) = " << imodp( 3 ) << " failed." << endl ;
1713         status = false ;
1714     }
1715     else
1716         fout_ << ".........PASS!" ;
1717 
1718     fout_ << "\nTEST:  IsPrimitiveRoot.   3 is a primitive root of 7." ;
1719     IsPrimitiveRoot isroot( 7 ) ;
1720     if (isroot( 3 ))
1721         fout_ << ".........PASS!" ;
1722     else
1723     {
1724         fout_ << "\n\tERROR:  IsPrimitiveRoot( 7 ) isroot ;  isroot( 3 ) = " << isroot( 3 ) << " failed." << endl ;
1725         status = false ;
1726     }
1727 
1728     fout_ << "\nTEST:  IsPrimitiveRoot.   2 is a primitive root of 11." ;
1729     IsPrimitiveRoot isroot11( 11 ) ;
1730     if (isroot11( 2 ))
1731         fout_ << ".........PASS!" ;
1732     else
1733     {
1734         fout_ << "\n\tERROR:  IsPrimitiveRoot( 11 ) isroot11 ;  isroot11( 2 ) = " << isroot11( 2 ) << " failed." << endl ;
1735         status = false ;
1736     }
1737 
1738     fout_ << "\nTEST:  IsPrimitiveRoot.   3 is NOT a primitive root of 11." ;
1739     if (isroot11( 3 ))
1740     {
1741         fout_ << "\n\tERROR:  IsPrimitiveRoot( 11 ) isroot11 ;  isroot11( 3 ) = " << isroot11( 3 ) << " failed." << endl ;
1742         status = false ;
1743     }
1744     else
1745         fout_ << ".........PASS!" ;
1746 
1747     fout_ << "\nTEST:  IsPrimitiveRoot.   5 is a primitive root of 65003." ;
1748     IsPrimitiveRoot isroot65003( 65003 ) ;
1749     if (isroot65003( 5 ))
1750         fout_ << ".........PASS!" ;
1751     else
1752     {
1753         fout_ << "\n\tERROR:  IsPrimitiveRoot65003( 5 ) should have said true.  It failed." << endl ;
1754         status = false ;
1755     }
1756 
1757     fout_ << "\nTEST:  IsPrimitiveRoot.   8 is NOT a primitive root of 65003." ;
1758     if (isroot65003( 8 ))
1759     {
1760         fout_ << "\n\tERROR:  IsPrimitiveRoot65003( 8 ) should have said false.  It failed." << endl ;
1761         status = false ;
1762     }
1763     else
1764         fout_ << ".........PASS!" ;
1765 
1766     fout_ << "\nTEST:  constant coefficient test." ;
1767     ArithModP arith1( 5 ) ;
1768     if (arith1.constCoeffTest( 4, 1, 11 ))
1769         fout_ << ".........PASS!" ;
1770     else
1771     {
1772         fout_ << "\n\tERROR:  constant coefficient test failed = " << arith1.constCoeffTest( 4, 1, 11 ) << " failed." << endl ;
1773         status = false ;
1774     }
1775 
1776     fout_ << "\nTEST:  constant coefficient is primitive root." ;
1777     ArithModP arith2( 7 ) ;
1778     if (arith2.constCoeffIsPrimitiveRoot( 4, 11 ))
1779         fout_ << ".........PASS!" ;
1780     else
1781     {
1782         fout_ << "\n\tERROR:  constant coefficient test failed = " << arith1.constCoeffIsPrimitiveRoot( 4, 11 ) << " failed." << endl ;
1783         status = false ;
1784     }
1785 
1786     fout_ << "\nTEST:  UniformRandomIntegers with range [0, 11)" ;
1787     ppuint range{ 11u } ;
1788     UniformRandomIntegers<ppuint> randum( range ) ;
1789     ppuint ran1{ randum.rand() } ;
1790     if (ran1 >= 0u && ran1 < range)
1791         fout_ << ".........PASS!" ;
1792     else
1793     {
1794         fout_ << "\n\tERROR:  random number generator out of range.  num = " << ran1 << " not in range [0, " << range << ")" << " failed." << endl ;
1795         status = false ;
1796     }
1797 
1798     fout_ << "\nTEST:  isProbablyPrime on ppuint prime 97 with random x = 10" ;
1799     if ( isProbablyPrime( static_cast<ppuint>( 97u ), static_cast<ppuint>( 10u ) ) == Primality::ProbablyPrime)
1800         fout_ << ".........PASS!" ;
1801     else
1802     {
1803         fout_ << ".........FAIL!" << endl ;
1804         status = false ;
1805     }
1806 
1807     fout_ << "\nTEST:  isAlmostSurelyPrime for ppuint prime 97" ;
1808     if ( isAlmostSurelyPrime( static_cast<ppuint>( 97u ) ))
1809         fout_ << ".........PASS!" ;
1810     else
1811     {
1812         fout_ << ".........FAIL!" << endl ;
1813         status = false ;
1814     }
1815 
1816     fout_ << "\nTEST:  isAlmostSurelyPrime for BigInt prime 97" ;
1817     if ( isAlmostSurelyPrime( static_cast<BigInt>( "97" ) ))
1818         fout_ << ".........PASS!" ;
1819     else
1820     {
1821         fout_ << ".........FAIL!" << endl ;
1822         status = false ;
1823     }
1824 
1825     fout_ << "\nTEST:  isAlmostSurelyPrime for non-prime BigInt 49" ;
1826     if (isAlmostSurelyPrime( static_cast<BigInt>( 49u ) ))
1827     {
1828         fout_ << ".........FAIL!" << endl ;
1829         status = false ;
1830     }
1831     else
1832         fout_ << ".........PASS!" ;
1833 
1834     fout_ << "\nTEST:  isAlmostSurelyPrime on the 10000th prime number 104729 of ppuint type" ;
1835     if (isAlmostSurelyPrime( static_cast<ppuint>( 104729u )))
1836         fout_ << ".........PASS!" ;
1837     else
1838     {
1839         fout_ << ".........FAIL!" << endl ;
1840         status = false ;
1841     }
1842 
1843     return status ;
1844 }
1845 
1846 
1847 bool UnitTest::unitTestFactoring()
1848 {
1849     bool status = true ;
1850 
1851     fout_ << "\nTEST:  Factor table method used on unsigned int 3^20 - 1 = 3486784400 = 2^4 5^2 11^2 61 1181" ;
1852 
1853     // 3^20 - 1 = 3486784400 = 2^4 5^2 11^2 61 1181
1854     ppuint num{ 3486784400 } ;
1855     ppuint   p{ 3 } ;
1856     ppuint   n{ 20 } ;
1857 
1858     Factorization<ppuint> f( num, FactoringAlgorithm::FactorTable, p, n ) ;
1859     vector<ppuint> df = f.getDistinctPrimeFactors() ;
1860 
1861     if (!(f.multiplicity(0) == 4 && f.primeFactor(0) ==    2u && f.primeFactor(0) == df[0] &&
1862           f.multiplicity(1) == 2 && f.primeFactor(1) ==    5u && f.primeFactor(1) == df[1] &&
1863           f.multiplicity(2) == 2 && f.primeFactor(2) ==   11u && f.primeFactor(2) == df[2] &&
1864           f.multiplicity(3) == 1 && f.primeFactor(3) ==   61u && f.primeFactor(2) == df[2] &&
1865           f.multiplicity(4) == 1 && f.primeFactor(4) == 1181u && f.primeFactor(2) == df[2] ))
1866     {
1867         fout_ << "\n\tERROR:  Table lookup factoring on unsigned int." << endl ;
1868         status = false ;
1869 
1870         fout_ << "\tFactor<ppuint> failed on 337500 = 2^2 3^3 5^5." << endl ;
1871         fout_ << "\tNumber of factors = " << f.numDistinctFactors() << endl ;
1872         fout_ << "\tFactors = " << endl ;
1873         for (unsigned int i = 0 ;  i < f.numDistinctFactors() ;  ++i)
1874             fout_ << f.primeFactor( i ) << " ^ " << f.multiplicity( i ) << " " ;
1875         fout_ << endl ;
1876     }
1877     else
1878         fout_ << ".........PASS!" ;
1879 
1880 
1881     fout_ << "\nTEST:  Factor table method used on BigInt 3^20 - 1 = 3486784400 = 2^4 5^2 11^2 61 1181" ;
1882 
1883     // 3^20 - 1 = 3486784400 = 2^4 5^2 11^2 61 1181
1884     BigInt num1{ 3486784400u } ;
1885     ppuint   p1{ 3 } ;
1886     ppuint   n1{ 20 } ;
1887 
1888     Factorization<BigInt> f1( num1, FactoringAlgorithm::FactorTable, p1, n1 ) ;
1889     vector<BigInt> df1 = f1.getDistinctPrimeFactors() ;
1890 
1891     if (!(f1.multiplicity(0) == 4 && f1.primeFactor(0) == static_cast<BigInt>(    2u ) && f1.primeFactor(0) == df[0] &&
1892           f1.multiplicity(1) == 2 && f1.primeFactor(1) == static_cast<BigInt>(    5u ) && f1.primeFactor(1) == df[1] &&
1893           f1.multiplicity(2) == 2 && f1.primeFactor(2) == static_cast<BigInt>(   11u ) && f1.primeFactor(2) == df[2] &&
1894           f1.multiplicity(3) == 1 && f1.primeFactor(3) == static_cast<BigInt>(   61u ) && f1.primeFactor(2) == df[2] &&
1895           f1.multiplicity(4) == 1 && f1.primeFactor(4) == static_cast<BigInt>( 1181u ) && f1.primeFactor(2) == df[2] ))
1896     {
1897         fout_ << "\n\tERROR:  Table lookup factoring on unsigned int." << endl ;
1898         status = false ;
1899 
1900         fout_ << "\tFactor<BigInt> failed on 337500 = 2^2 3^3 5^5." << endl ;
1901         fout_ << "\tNumber of factors = " << f.numDistinctFactors() << endl ;
1902         fout_ << "\tFactors = " << endl ;
1903         for (unsigned int i = 0 ;  i < f.numDistinctFactors() ;  ++i)
1904             fout_ << f.primeFactor( i ) << " ^ " << f.multiplicity( i ) << " " ;
1905         fout_ << endl ;
1906     }
1907     else
1908         fout_ << ".........PASS!" ;
1909 
1910 
1911     fout_ << "\nTEST:  Trial division factoring on unsigned int 337500 = 2^2 3^3 5^5." ;
1912 
1913     Factorization<ppuint> f2( 337500u, FactoringAlgorithm::TrialDivisionAlgorithm ) ;
1914     vector<ppuint> df2 = f2.getDistinctPrimeFactors() ;
1915 
1916     if (!(f2.multiplicity(0) == 2 && f2.primeFactor(0) == 2u && f2.primeFactor(0) == df2[0] &&
1917           f2.multiplicity(1) == 3 && f2.primeFactor(1) == 3u && f2.primeFactor(1) == df2[1] &&
1918           f2.multiplicity(2) == 5 && f2.primeFactor(2) == 5u && f2.primeFactor(2) == df2[2] ))
1919     {
1920         fout_ << "\n\tERROR:  Trial division factoring on unsigned int." << endl ;
1921         status = false ;
1922 
1923         fout_ << "\tFactor<ppuint> failed on 337500 = 2^2 3^3 5^5." << endl ;
1924         fout_ << "\tNumber of factors = " << f2.numDistinctFactors() << endl ;
1925         fout_ << "\tFactors = " << endl ;
1926         for (unsigned int i = 0 ;  i < f2.numDistinctFactors() ;  ++i)
1927             fout_ << f2.primeFactor( i ) << " ^ " << f2.multiplicity( i ) << " " ;
1928         fout_ << endl ;
1929     }
1930     else
1931         fout_ << ".........PASS!" ;
1932 
1933 
1934     fout_ << "\nTEST:  Trial division factoriing on BigInt 337500 = 2^2 3^3 5^5." ;
1935 
1936     Factorization<BigInt> f3( static_cast<BigInt>("337500"), FactoringAlgorithm::TrialDivisionAlgorithm ) ;
1937     vector<BigInt> df3{ f3.getDistinctPrimeFactors() } ;
1938 
1939     if (!(f3.multiplicity(0) == 2u  && f3.primeFactor( 0 ) == static_cast<BigInt>( 2u ) && f3.primeFactor( 0 ) == df3[0] &&
1940           f3.multiplicity(1) == 3u  && f3.primeFactor( 1 ) == static_cast<BigInt>( 3u ) && f3.primeFactor( 1 ) == df3[1] &&
1941           f3.multiplicity(2) == 5u  && f3.primeFactor( 2 ) == static_cast<BigInt>( 5u ) && f3.primeFactor( 2 ) == df3[2] ))
1942     {
1943         fout_ << "\n\tERROR:Factorization<BigInt> failed on 337500 = 2^2 3^3 5^5." << endl ;
1944         status = false ;
1945 
1946         fout_ << "Number of factors = " << f3.numDistinctFactors() << endl ;
1947         fout_ << "Factors = " << endl ;
1948         for (unsigned int i = 0 ;  i < f3.numDistinctFactors() ;  ++i)
1949             fout_ << f3.primeFactor( i ) << " ^ " << f3.multiplicity( i ) << " " ;
1950         fout_ << endl ;
1951     }
1952     else
1953         fout_ << ".........PASS!" ;
1954 
1955 
1956     fout_ << "\nTEST:  Pollard Rho factorization on unsigned int 25852 = 2^2 23 281" ;
1957 
1958     Factorization<ppuint> fr( 25852u, FactoringAlgorithm::pollardRhoAlgorithm ) ;
1959     vector<ppuint> dfr = fr.getDistinctPrimeFactors() ;
1960 
1961     if ( !(fr.multiplicity(0) == 2 && fr.primeFactor(0) ==  2u  && fr.primeFactor(0) == dfr[0] &&
1962            fr.multiplicity(1) == 1 && fr.primeFactor(1) == 23u  && fr.primeFactor(1) == dfr[1] &&
1963            fr.multiplicity(2) == 1 && fr.primeFactor(2) == 281u && fr.primeFactor(2) == dfr[2] ))
1964     {
1965         fout_ << "\n\tERROR:Factorization<ppuint> failed on 25852 = 2^2 23 281." << endl ;
1966 
1967         status = false ;
1968         fout_ << "Number of factors = " << fr.numDistinctFactors() << endl ;
1969         fout_ << "Factors = " << endl ;
1970         for (unsigned int i = 0 ;  i < fr.numDistinctFactors() ;  ++i)
1971             fout_ << fr.primeFactor( i ) << " ^ " << fr.multiplicity( i ) << " " ;
1972         fout_ << endl ;
1973     }
1974     else
1975         fout_ << ".........PASS!" ;
1976 
1977 
1978     fout_ << "\nTEST:  Pollard Rho factorization on BigInt 25852 = 2^2 23 281" ;
1979 
1980     Factorization<BigInt> frb( static_cast<BigInt>( 25852u ), FactoringAlgorithm::pollardRhoAlgorithm ) ;
1981     vector<BigInt> dfrb = frb.getDistinctPrimeFactors() ;
1982 
1983     if ( !(frb.multiplicity(0) == 2 && frb.primeFactor(0) == static_cast<BigInt>( 2u   ) && frb.primeFactor(0) == dfrb[0] &&
1984            frb.multiplicity(1) == 1 && frb.primeFactor(1) == static_cast<BigInt>( 23u  ) && frb.primeFactor(1) == dfrb[1] &&
1985            frb.multiplicity(2) == 1 && frb.primeFactor(2) == static_cast<BigInt>( 281u ) && frb.primeFactor(2) == dfrb[2] ))
1986     {
1987         fout_ << "\n\tERROR:Factorization<BigInt> failed on 25852 = 2^2 23 281." << endl ;
1988 
1989         status = false ;
1990         fout_ << "Number of factors = " << frb.numDistinctFactors() << endl ;
1991         fout_ << "Factors = " << endl ;
1992         for (unsigned int i = 0 ;  i < frb.numDistinctFactors() ;  ++i)
1993             fout_ << frb.primeFactor( i ) << " ^ " << frb.multiplicity( i ) << " " ;
1994         fout_ << endl ;
1995     }
1996     else
1997         fout_ << ".........PASS!" ;
1998 
1999 
2000     fout_ << "\nTEST:  BigInt computation of p^n, r, factors of r, EulerPhi[ p^n - 1]/n for p = 2" ;
2001     {
2002         try
2003         {
2004             ppuint p{ 2u } ;
2005             ppuint n{ 36u } ;
2006 
2007             //                                             n
2008             // Create a polynomial of degree n modulo p:  x  + 1
2009             Polynomial f ;
2010             f.initialTrialPoly( n, p ) ;
2011 
2012             // We'll do the factorization here.
2013             PolyOrder order( f ) ;
2014 
2015             if ( !( order.getMaxNumPoly() == static_cast<BigInt>( "68719476736" ) && order.getR()  == static_cast<BigInt>( "68719476735" ) &&
2016                     order.getFactorsOfR().primeFactor(0) == static_cast<BigInt>(  3u ) &&
2017                     order.getFactorsOfR().multiplicity(0) == 3 &&
2018                     order.getFactorsOfR().primeFactor(1) == static_cast<BigInt>(  5u ) &&
2019                     order.getFactorsOfR().multiplicity(1) == 1 &&
2020                     order.getFactorsOfR().primeFactor(2) == static_cast<BigInt>(  7u ) &&
2021                     order.getFactorsOfR().multiplicity(2) == 1 &&
2022                     order.getFactorsOfR().primeFactor(3) == static_cast<BigInt>( 13u ) &&
2023                     order.getFactorsOfR().multiplicity(3) == 1 &&
2024                     order.getFactorsOfR().primeFactor(4) == static_cast<BigInt>( 19u ) &&
2025                     order.getFactorsOfR().multiplicity(4) == 1 &&
2026                     order.getFactorsOfR().primeFactor(5) == static_cast<BigInt>( 37u ) &&
2027                     order.getFactorsOfR().multiplicity(5) == 1 &&
2028                     order.getFactorsOfR().primeFactor(6) == static_cast<BigInt>( 73u ) &&
2029                     order.getFactorsOfR().multiplicity(6) == 1 &&
2030                     order.getFactorsOfR().primeFactor(7) == static_cast<BigInt>(109u ) &&
2031                     order.getFactorsOfR().multiplicity(7) == 1 &&
2032                     order.getNumPrimPoly() == static_cast<BigInt>( "725594112" )
2033                 ))
2034             {
2035                 fout_ << "\n\tERROR:  BigInt computation of p^n, r, factors of r, EulerPhi[ p^n - 1]/n for p = 2" << endl ;
2036                 status = false ;
2037 
2038                 fout_ << "p = " << p << endl ;
2039                 fout_ << "n = " << n << endl ;
2040                 fout_ << "max_num_possible_poly = " << order.getMaxNumPoly() << endl ;
2041                 fout_ << "r = " << order.getR() << endl ;
2042                 fout_ << "r:  Number of factors = " << order.getFactorsOfR().numDistinctFactors() << endl ;
2043                 fout_ << "Factors = " << endl ;
2044                 for (unsigned int i = 0 ;  i < order.getFactorsOfR().numDistinctFactors() ;  ++i)
2045                     fout_ << order.getFactorsOfR().primeFactor( i ) << " ^ " << order.getFactorsOfR().multiplicity( i ) << " " ;
2046                 fout_ << endl ;
2047 
2048                 fout_ << "num_primitive_poly = " << order.getNumPrimPoly() << endl ;
2049             }
2050             else
2051                 fout_ << ".........PASS!" ;
2052         }
2053         catch( BigIntMathError & e )
2054         {
2055             fout_ << ".........FAIL!" << endl ;
2056             fout_ << "    caught BigIntMathError: [ " << e.what() << " ] " << endl ;
2057             status = false ;
2058         }
2059         catch( FactorError & e )
2060         {
2061             fout_ << ".........FAIL!" << endl ;
2062             fout_ << "    caught FactorError: [ " << e.what() << " ] " << endl ;
2063             status = false ;
2064         }
2065     }
2066 
2067 
2068     fout_ << "\nTEST:  Factor Copy constructor" ;
2069     Factorization<BigInt> fact( f3 ) ;
2070     vector<BigInt> dfact = fact.getDistinctPrimeFactors() ;
2071     if (!(fact.multiplicity(0) == 2 && fact.primeFactor(0) == static_cast<BigInt>( 2u ) && fact.primeFactor(0) == dfact[0] &&
2072           fact.multiplicity(1) == 3 && fact.primeFactor(1) == static_cast<BigInt>( 3u ) && fact.primeFactor(1) == dfact[1] &&
2073           fact.multiplicity(2) == 5 && fact.primeFactor(2) == static_cast<BigInt>( 5u ) && fact.primeFactor(2) == dfact[2] ))
2074     {
2075         fout_ << "\n\tERROR:  Factor copy constructor failed on 337500 = 2^2 3^3 5^5." << endl ;
2076         status = false ;
2077 
2078         fout_ << "Number of factors = " << fact.numDistinctFactors() << endl ;
2079         fout_ << "Factors = " << endl ;
2080         for (unsigned int i = 0 ;  i < fact.numDistinctFactors() ;  ++i)
2081             fout_ << fact.primeFactor( i ) << " ^ " << fact.multiplicity( i ) << " " ;
2082         fout_ << endl ;
2083     }
2084     else
2085         fout_ << ".........PASS!" ;
2086 
2087 
2088 
2089     fout_ << "\nTEST:  Factor assignment operator" ;
2090     Factorization<BigInt> fact1 ;
2091     fact1 = f3 ;
2092     vector<BigInt> dfact1 = fact1.getDistinctPrimeFactors() ;
2093     if (!(fact1.multiplicity(0) == 2 && fact1.primeFactor(0) == static_cast<BigInt>( 2u ) && dfact1[0] == fact1.primeFactor(0) &&
2094           fact1.multiplicity(1) == 3 && fact1.primeFactor(1) == static_cast<BigInt>( 3u ) && dfact1[1] == fact1.primeFactor(1) &&
2095           fact1.multiplicity(2) == 5 && fact1.primeFactor(2) == static_cast<BigInt>( 5u ) && dfact1[2] == fact1.primeFactor(2) ))
2096     {
2097         fout_ << "\n\tERROR:  Factor assignment operator failed on 337500 = 2^2 3^3 5^5." << endl ;
2098         status = false ;
2099 
2100         fout_ << "Number of factors = " << fact1.numDistinctFactors() << endl ;
2101         fout_ << "Factors = " << endl ;
2102         for (unsigned int i = 0 ;  i < fact1.numDistinctFactors() ;  ++i)
2103             fout_ << fact1.primeFactor( i ) << " ^ " << fact1.multiplicity( i ) << " " ;
2104         fout_ << endl ;
2105     }
2106     else
2107         fout_ << ".........PASS!" ;
2108 
2109     return status ;
2110 }
2111 
2112 
2113 bool UnitTest::unitTestPolynomials()
2114 {
2115     bool status = true ;
2116 
2117     fout_ << "\nTEST:  Polynomial() default constructor." ;
2118     {
2119         Polynomial p ;
2120         if (p.deg() != 0)
2121         {
2122             fout_ << "\n\tERROR: Polynomial default constructor failed." << endl ;
2123             status = false ;
2124         }
2125         else
2126             fout_ << ".........PASS!" ;
2127     }
2128 
2129     fout_ << "\nTEST:  Polynomial() from string." ;
2130     {
2131         Polynomial p( "2x^2 + 1, 3" ) ;
2132         if (p.deg() != 2 || p.modulus() != 3 || p[0] != 1 || p[1] != 0 || p[2] != 2)
2133         {
2134             fout_ << "\n\tERROR: Polynomial p( \"2x^2 + 1, 3\" ) failed." << endl ;
2135             status = false ;
2136         }
2137         else
2138             fout_ << ".........PASS!" ;
2139     }
2140 
2141     fout_ << "\nTEST:  Polynomial = string." ;
2142     {
2143         Polynomial p ;
2144         p = "2x^2 + 1, 3" ;
2145         if (p.deg() != 2 || p.modulus() != 3 || p[0] != 1 || p[1] != 0 || p[2] != 2)
2146         {
2147             fout_ << "\n\tERROR: Polynomial p = string \"2x^2 + 1, 3\" ) failed." << endl ;
2148             status = false ;
2149         }
2150         else
2151             fout_ << ".........PASS!" ;
2152     }
2153 
2154     fout_ << "\nTEST:  Polynomial() from string with negative constant should give a parser error." ;
2155     try
2156     {
2157         Polynomial p( "x^4-1, 5" ) ;
2158         fout_ << "\n\tERROR: Polynomial with negative constant failed to throw an exception " << endl ;
2159         status = false ;
2160     }
2161     catch( PolynomialRangeError & e )
2162     {
2163         // Match only the error message.
2164         // The file name and line number where the error occurred may change with different versions of this software.
2165         string trueErrorMessage = "Error in parser converting polynomial from string x^4-1, 5 for p = 2 Error:  negative number for a polynomial coefficient = -1 is not allowed.  Numbers must be >= 0" ;
2166         if (static_cast<string>(e.what()).find( trueErrorMessage ) == string::npos)
2167         {
2168             fout_ << "\n\tERROR:  Incorrect error message = |" << e.what() << "|" << endl ;
2169             status = false ;
2170         }
2171         else
2172             fout_ << ".........PASS!" ;
2173     }
2174 
2175     fout_ << "\nTEST:  Polynomial() to string." ;
2176     {
2177         Polynomial p ; // ( "2x^2 + 1, 3" )
2178         Polynomial q( p ) ;
2179         p[0] = 1 ; p[2] = 2 ;
2180         p.setModulus( 3 ) ;
2181         string s = p ;
2182         if (s != "2 x ^ 2 + 1, 3")
2183         {
2184             fout_ << "\n\tERROR: Polynomial p( \"2x^2 + 1, 3\" ) to string s = " << s << " failed." << endl ;
2185             status = false ;
2186         }
2187         else
2188             fout_ << ".........PASS!" ;
2189     }
2190 
2191     fout_ << "\nTEST:  Polynomial() copy constructor." ;
2192     try
2193     {
2194         Polynomial p( "2x^2 + 1, 3" ) ;
2195         Polynomial q( p ) ;
2196         if (static_cast<string>(q) != "2 x ^ 2 + 1, 3")
2197         {
2198             fout_ << "\n\tERROR: Polynomial copy constructor p( q ) = " << q << " failed." << endl ;
2199             status = false ;
2200         }
2201         else
2202             fout_ << ".........PASS!" ;
2203     }
2204     catch( PolynomialRangeError & e )
2205     {
2206         fout_ << "\n\tERROR:  PolynomialRangeError error:  copy constructor failed [ " << e.what() << " ] " << endl ;
2207         status = false ;
2208     }
2209 
2210     fout_ << "\nTEST:  Polynomial equality test operator==()." ;
2211     try
2212     {
2213         Polynomial p1( "2x^2 + 1, 3" ) ;
2214         Polynomial p2( "2x^2 + 1, 3" ) ;
2215         if (p1 == p2)
2216             fout_ << ".........PASS!" ;
2217         else
2218         {
2219             fout_ << "\n\tERROR: Polynomial " << p1 << " == " << p2 << " failed." << endl ;
2220             status = false ;
2221         }
2222     }
2223     catch( PolynomialRangeError & e )
2224     {
2225         fout_ << "\n\tERROR:  PolynomialRangeError error:  operator()== failed [ " << e.what() << " ] " << endl ;
2226         status = false ;
2227     }
2228 
2229     fout_ << "\nTEST:  Polynomial inequality test operator!=()." ;
2230     try
2231     {
2232         Polynomial p1( "2x^2 + 1, 3" ) ;
2233         Polynomial p2( "2x^2 + x + 1, 3" ) ;
2234         if (p1 != p2)
2235             fout_ << ".........PASS!" ;
2236         else
2237         {
2238             fout_ << "\n\tERROR: Polynomial " << p1 << " != " << p2 << " failed." << endl ;
2239             status = false ;
2240         }
2241     }
2242     catch( PolynomialRangeError & e )
2243     {
2244         fout_ << "\n\tERROR:  PolynomialRangeError error:  operator()!= failed [ " << e.what() << " ] " << endl ;
2245         status = false ;
2246     }
2247 
2248     fout_ << "\nTEST:  Polynomial assignment operator." ;
2249     try
2250     {
2251         Polynomial p( "2x^2 + 1, 3" ) ;
2252         Polynomial q ;
2253         q = p ; // If we did Polynomial q = p it would call the copy constructor.
2254         if (static_cast<string>(q) != "2 x ^ 2 + 1, 3")
2255         {
2256             fout_ << "\n\tERROR: Polynomial assignment operator p = q " << q << " failed." << endl ;
2257             status = false ;
2258         }
2259         else
2260             fout_ << ".........PASS!" ;
2261     }
2262     catch( PolynomialRangeError & e )
2263     {
2264         fout_ << "\n\tERROR:  PolynomialRangeError error:  assignment operator p = q failed [ " << e.what() << " ] " << endl ;
2265         status = false ;
2266     }
2267 
2268     fout_ << "\nTEST:  Polynomial()[] read only operator." ;
2269     try
2270     {
2271         Polynomial p( "2x^2 + 1, 3" ) ;
2272         if (p[ 0 ] == 1 && p[ 1 ] == 0 && p[ 2 ] == 2)
2273            fout_ << ".........PASS!" ;
2274         else
2275         {
2276             fout_ << "\n\tERROR:  Polynomial [] read only failed on reading p[0], p[1], p[2]." << endl ;
2277             status = false ;
2278         }
2279     }
2280     catch( PolynomialRangeError & e )
2281     {
2282         fout_ << "\n\tERROR:  Polynomial [] read only failed on reading p[0], p[1], p[2] [ " << e.what() << " ] " << endl ;
2283         status = false ;
2284     }
2285 
2286     fout_ << "\nTEST:  Polynomial()[] accessing coeff higher than its degree." ;
2287     try
2288     {
2289         const Polynomial p( "2x^2 + 1, 3" ) ;
2290         ppuint z{ p[ 3 ] } ;
2291 
2292         fout_ << "\n\tERROR:  Polynomial [] failed to throw exception on accessing p[3] = " << z << endl ;
2293         fout_ << "poly = " << p << " deg of p = " << p.deg() << endl ;
2294         status = false ;
2295     }
2296     catch( PolynomialRangeError & e )
2297     {
2298         fout_ << ".........PASS!" ;
2299     }
2300 
2301     fout_ << "\nTEST:  Polynomial()[] lvalue operator." ;
2302     try
2303     {
2304         Polynomial p( "2x^2 + 1, 3" ) ;
2305         int oldDeg{ p.deg() } ;
2306         p[ 5 ] = 2 ;
2307         p[ 1 ] = 1 ;
2308         int newDeg = p.deg() ;
2309         if (static_cast<string>(p) != "2 x ^ 5 + 2 x ^ 2 + x + 1, 3" || oldDeg != 2 || newDeg != 5)
2310         {
2311             fout_ << "\n\tERROR: Polynomial [] lvalue operator " << p << " failed." << endl ;
2312             status = false ;
2313         }
2314         else
2315             fout_ << ".........PASS!" ;
2316     }
2317     catch( PolynomialRangeError & e )
2318     {
2319         fout_ << "\n\tERROR:  Polynomial [] failed [ " << e.what() << " ] " << endl ;
2320         status = false ;
2321     }
2322 
2323     fout_ << "\nTEST:  Polynomial() += operator." ;
2324     try
2325     {
2326         Polynomial p( "2x^2 + 1, 3" ) ;
2327         Polynomial q( " x^2 + 1, 3" ) ;
2328         p += q ;
2329         if (p.deg() != 1 && static_cast<string>(p) != "2, 3")
2330         {
2331             fout_ << "\n\tERROR: Polynomial += " << p << " failed." << endl ;
2332             status = false ;
2333         }
2334         else
2335             fout_ << ".........PASS!" ;
2336     }
2337     catch( PolynomialRangeError & e )
2338     {
2339         fout_ << "\n\tERROR:  Polynomial += failed. [ " << e.what() << " ] " << endl ;
2340         status = false ;
2341     }
2342 
2343     fout_ << "\nTEST:  Polynomial() += operator." ;
2344     try
2345     {
2346         Polynomial p( "2x^2 + 1, 3" ) ;
2347         Polynomial q( " x^2 + 2, 3" ) ;
2348         p += q ;
2349         if (p.deg() != 0 && static_cast<string>(p) != "0, 3")
2350         {
2351             fout_ << "\n\tERROR: Polynomial += " << p << " failed." << endl ;
2352             status = false ;
2353         }
2354         else
2355             fout_ << ".........PASS!" ;
2356     }
2357     catch( PolynomialRangeError & e )
2358     {
2359         fout_ << "\n\tERROR:  Polynomial += failed [ " << e.what() << " ] " << endl ;
2360         status = false ;
2361     }
2362 
2363     fout_ << "\nTEST:  Polynomial() + operator." ;
2364     try
2365     {
2366         Polynomial p( "2x^2 + 1, 3" ) ;
2367         Polynomial q( " x^2 + 1, 3" ) ;
2368         Polynomial r = p + q ;
2369         if (static_cast<string>(r) != "2, 3")
2370         {
2371             fout_ << "\n\tERROR: Polynomial + " << r << " failed." << endl ;
2372             status = false ;
2373         }
2374         else
2375             fout_ << ".........PASS!" ;
2376     }
2377     catch( PolynomialRangeError & e )
2378     {
2379         fout_ << "\n\tERROR:  Polynomial + failed [ " << e.what() << " ] " << endl ;
2380         status = false ;
2381     }
2382 
2383     fout_ << "\nTEST:  Polynomial * scalar" ;
2384     try
2385     {
2386         Polynomial p( "2x^2 + 1, 3" ) ;
2387         ppuint k{ 2 } ;
2388 
2389         Polynomial q = p * k ;
2390         if (static_cast<string>(q) != "x ^ 2 + 2, 3")
2391         {
2392             fout_ << "\n\tERROR: Polynomial * scalar operator " << q << " failed." << endl ;
2393             status = false ;
2394         }
2395         else
2396             fout_ << ".........PASS!" ;
2397     }
2398     catch( PolynomialRangeError & e )
2399     {
2400         fout_ << "\n\tERROR:  PolynomialRangeError error:  * scalar failed [ " << e.what() << " ] " << endl ;
2401         status = false ;
2402     }
2403 
2404 
2405     fout_ << "\nTEST:  Polynomial evaluation x^4 + 3x + 3 (mod 5)" ;
2406     {
2407         Polynomial p( "x^4 + 3x + 3, 5" ) ;
2408         ppuint f2{ p( 2 ) } ;
2409         ppuint f3{ p( 3 ) } ;
2410         ppuint f0{ p( 0 ) } ;
2411         if (f2 != 0 || f3 != 3 || f0 != 3)
2412         {
2413             fout_ << "\n\tERROR: Polynomial operator() = " << f2 << f3 << f0 << " failed." << endl ;
2414             status = false ;
2415         }
2416         else
2417             fout_ << ".........PASS!" ;
2418     }
2419 
2420     fout_ << "\nTEST:  Polynomial evaluation x^4 + x + 1 (mod 2)" ;
2421     {
2422         Polynomial p( "x^4 + x + 1, 2" ) ;
2423         ppuint f0{ p( 0 ) } ;
2424         ppuint f1{ p( 1 ) } ;
2425         if (f0 != 1 || f1 != 1)
2426         {
2427             fout_ << "\n\tERROR: Polynomial operator() = " << f0 << f1 << " failed." << endl ;
2428             status = false ;
2429         }
2430         else
2431             fout_ << ".........PASS!" ;
2432     }
2433 
2434     fout_ << "\nTEST:  Polynomial hasLinearFactor is true" ;
2435     {
2436         Polynomial p( "x^4 + 3x + 3, 5" ) ;
2437         bool linFac = p.hasLinearFactor() ;
2438             if (linFac)
2439                 fout_ << ".........PASS!" ;
2440             else
2441             {
2442                 fout_ << "\n\tERROR: Polynomial hasLinearFactor = " << linFac << " failed." << endl ;
2443                 status = false ;
2444             }
2445         }
2446 
2447     fout_ << "\nTEST:  Polynomial hasLinearFactor is false" ;
2448     {
2449         Polynomial p( "x^4 + 3x^2 + x + 1, 5" ) ;
2450         bool linFac = p.hasLinearFactor() ;
2451         if (!linFac)
2452             fout_ << ".........PASS!" ;
2453         else
2454         {
2455             fout_ << "\n\tERROR: Polynomial hasLinearFactor = " << linFac << " failed." << endl ;
2456             status = false ;
2457         }
2458     }
2459 
2460     fout_ << "\nTEST:  Polynomial isInteger" ;
2461     try
2462     {
2463         Polynomial p( "x^4 + 3x + 3, 5" ) ;
2464         bool isInt = p.isInteger() ;
2465         if (!isInt)
2466             fout_ << ".........PASS!" ;
2467         else
2468         {
2469             fout_ << "\n\tERROR: Polynomial " << p << " isInteger = " << isInt << " failed." << endl ;
2470             status = false ;
2471         }
2472 
2473         Polynomial q( "3, 5" ) ;
2474         isInt = q.isInteger() ;
2475         if (isInt)
2476             fout_ << ".........PASS!" ;
2477         else
2478         {
2479             fout_ << "\n\tERROR: Polynomial " << q << " isInteger = " << isInt << " failed." << endl ;
2480             status = false ;
2481         }
2482 
2483     }
2484     catch( PolynomialRangeError & e )
2485     {
2486         fout_ << "\n\tERROR:  PolynomialRangeError error: polynomial operator() failed [ " << e.what() << " ] " << endl ;
2487         status = false ;
2488     }
2489 
2490     fout_ << "\nTEST:  Polynomial initial and next trial polynomials" ;
2491     try {
2492         Polynomial p ;
2493         p.initialTrialPoly( 4, 5 ) ;
2494 
2495         for (int i = 1 ;  i <= 3 ; ++i)
2496         {
2497             p.nextTrialPoly() ;
2498         }
2499         if (static_cast<string>(p) == "x ^ 4 + 3, 5")
2500             fout_ << ".........PASS!" ;
2501         else
2502         {
2503             fout_ << "\n\tERROR: Polynomial " << p << " (3rd iteration from x^n initial) failed." << endl ;
2504             status = false ;
2505         }
2506 
2507     }
2508     catch( PolynomialRangeError & e )
2509     {
2510         fout_ << "\n\tERROR:  PolynomialRangeError error: polynomial operator() failed [ " << e.what() << " ] " << endl ;
2511         status = false ;
2512     }
2513 
2514     ////////////////////////////////////////////////////////////////////////
2515     // Test polynomial mod
2516     ////////////////////////////////////////////////////////////////////////
2517 
2518     fout_ << "\nTEST:  PolyMod constructor from polynomials." ;
2519     try {
2520         Polynomial g( "x^4 + x^2 + 1,2" ) ;
2521         Polynomial f( "x^4 + x + 1,2" ) ;
2522 
2523         PolyMod p( g, f ) ;
2524         if (static_cast<string>(p) == "x ^ 2 + x, 2" &&
2525             static_cast<string>( p.getf() ) == "x ^ 4 + x + 1, 2" && p.getModulus() == 2)
2526             fout_ << ".........PASS!" ;
2527         else
2528         {
2529             fout_ << "\n\tERROR: PolyMod constructor from polynomials, g(x)  = " << p << " failed." << endl ;
2530             status = false ;
2531         }
2532     }
2533     catch( PolynomialRangeError & e )
2534     {
2535         fout_ << "\n\tERROR:  PolynomialRangeError error: [ " << e.what() << " ] " << endl ;
2536         status = false ;
2537     }
2538 
2539     fout_ << "\nTEST:  PolyMod constructor from string and polynomial." ;
2540     try {
2541         Polynomial f( "x^4 + x^2 + 2x + 3, 5" ) ;
2542         PolyMod p( "x^6 + 2x^2 + 3x + 2, 5", f ) ;
2543 
2544         if (static_cast<string>(p) == "3 x ^ 3, 5" &&
2545             static_cast<string>( p.getf() ) == "x ^ 4 + x ^ 2 + 2 x + 3, 5" && p.getModulus() == 5)
2546             fout_ << ".........PASS!" ;
2547         else
2548         {
2549             fout_ << "\n\tERROR: PolyMod constructor from string and polynomial failed." << endl ;
2550             fout_ << "\ng(x) mod f(x), p = " << p << endl ;
2551             fout_ << "\nf(x) = " << f << endl ;
2552             status = false ;
2553         }
2554     }
2555     catch( PolynomialRangeError & e )
2556     {
2557         fout_ << "\n\tERROR:  PolynomialRangeError error: [ " << e.what() << " ] " << endl ;
2558         status = false ;
2559     }
2560 
2561     fout_ << "\nTEST:  PolyMod timesX." ;
2562     try {
2563         Polynomial g( "2x^3 + 4x^2 + 3x, 5" ) ;
2564         Polynomial f( "x^4 + x^2 + 2x + 3, 5" ) ;
2565 
2566         PolyMod p( g, f ) ;
2567 
2568         p.timesX() ;
2569         if (static_cast<string>(p) == "4 x ^ 3 + x ^ 2 + x + 4, 5" )
2570             fout_ << ".........PASS!" ;
2571         else
2572         {
2573             fout_ << "\n\tERROR: PolyMod timesX " << p << " failed." << endl ;
2574             status = false ;
2575         }
2576     }
2577     catch( PolynomialRangeError & e )
2578     {
2579         fout_ << "\n\tERROR:  PolynomialRangeError error: [ " << e.what() << " ] " << endl ;
2580         status = false ;
2581     }
2582 
2583     fout_ << "\nTEST:  PolyMod autoconvolve." ;
2584     try {
2585         Polynomial t( "4x^3 + x^2 + 3x + 3, 5" ) ;
2586         int k{ 3 } ; int lower{ 1 } ; int upper{ 3 } ;
2587         ppuint c{ autoConvolve( t, k, lower, upper ) } ;
2588 
2589         if (c == 3)
2590             fout_ << ".........PASS!" ;
2591         else
2592         {
2593             fout_ << "\n\tERROR: PolyMod autoconvolve = " << c
2594                  << " for t = " << t << " deg = " << t.deg() << " failed." << endl ;
2595             status = false ;
2596         }
2597     }
2598     catch( PolynomialRangeError & e )
2599     {
2600         fout_ << "\n\tERROR:  PolynomialRangeError autoconvolve [ " << e.what() << " ] " << endl ;
2601         status = false ;
2602     }
2603 
2604     fout_ << "\nTEST:  PolyMod convolve." ;
2605     try {
2606         Polynomial s( "4x^3 + x^2 + 3x + 3, 5" ) ;
2607         Polynomial t( "4x^3 + x^2 + 3x + 3, 5" ) ;
2608         int k{ 3 } ; int lower{ 1 } ; int upper{ 3 } ;
2609         ppuint c{ convolve( s, t, k, lower, upper ) } ;
2610 
2611         if (c == 3)
2612             fout_ << ".........PASS!" ;
2613         else
2614         {
2615             fout_ << "\n\tERROR: PolyMod convolve = " << c
2616                  << " for t = " << t << " deg = " << t.deg() << " failed." << endl ;
2617             status = false ;
2618         }
2619     }
2620     catch( PolynomialRangeError & e )
2621     {
2622         fout_ << "\n\tERROR:  PolynomialRangeError convolve [ " << e.what() << " ] " << endl ;
2623         status = false ;
2624     }
2625 
2626     fout_ << "\nTEST:  PolyMod coeffOfSquare." ;
2627     try {
2628         Polynomial g( "4x^3 + x^2 + 3x + 3, 5" ) ;
2629         int n = 4 ;
2630         ppuint c0{ coeffOfSquare( g, 0, n ) } ;
2631         ppuint c1{ coeffOfSquare( g, 1, n ) } ;
2632         ppuint c2{ coeffOfSquare( g, 2, n ) } ;
2633         ppuint c3{ coeffOfSquare( g, 3, n ) } ;
2634         ppuint c4{ coeffOfSquare( g, 4, n ) } ;
2635         ppuint c5{ coeffOfSquare( g, 5, n ) } ;
2636         ppuint c6{ coeffOfSquare( g, 6, n ) } ;
2637 
2638         if (c0 == 4 && c1 == 3 && c2 == 0 && c3 == 0 && c4 == 0 && c5 == 3 && c6 == 1)
2639             fout_ << ".........PASS!" ;
2640         else
2641         {
2642             fout_ << "\n\tERROR: PolyMod coeffOfSquare (c0 ... c6) = " << c0 << " " << c1 << " " << c2
2643                  << " " << c3 << " " << c4 << " " << c5 << " " << c6 << " failed." << endl ;
2644             status = false ;
2645         }
2646     }
2647     catch( PolynomialRangeError & e )
2648     {
2649         fout_ << "\n\tERROR:  PolynomialRangeError coeffOfSquare [ " << e.what() << " ] " << endl ;
2650         status = false ;
2651     }
2652 
2653     fout_ << "\nTEST:  PolyMod coeffOfProduct." ;
2654     try {
2655         Polynomial s( "4x^3 + x^2 + 4, 5" ) ;
2656         Polynomial t( "3x^2 + x + 2, 5" ) ;
2657         int n = 4 ;
2658         ppuint c0{ coeffOfProduct( s, t, 0, n ) } ;
2659         ppuint c1{ coeffOfProduct( s, t, 1, n ) } ;
2660         ppuint c2{ coeffOfProduct( s, t, 2, n ) } ;
2661         ppuint c3{ coeffOfProduct( s, t, 3, n ) } ;
2662         ppuint c4{ coeffOfProduct( s, t, 4, n ) } ;
2663         ppuint c5{ coeffOfProduct( s, t, 5, n ) } ;
2664         ppuint c6{ coeffOfProduct( s, t, 6, n ) } ;
2665 
2666         if (c0 == 3 && c1 == 4 && c2 == 4 && c3 == 4 && c4 == 2 && c5 == 2 && c6 == 0)
2667             fout_ << ".........PASS!" ;
2668         else
2669         {
2670             fout_ << "\n\tERROR: PolyMod coeffOfProduct (c0 ... c6) = " << c0 << " " << c1 << " " << c2
2671                  << " " << c3 << " " << c4 << " " << c5 << " " << c6 << " failed." << endl ;
2672             status = false ;
2673         }
2674     }
2675     catch( PolynomialRangeError & e )
2676     {
2677         fout_ << "\n\tERROR:  PolynomialRangeError coeffOfProduct [ " << e.what() << " ] " << endl ;
2678         status = false ;
2679     }
2680 
2681     fout_ << "\nTEST:  PolyMod square." ;
2682     try {
2683         Polynomial g( "4x^3 + x^2 + 4, 5" ) ;
2684         Polynomial f( "x^4 + x^2 + 2x + 3, 5" ) ;
2685 
2686         PolyMod p( g, f ) ;
2687 
2688         p.square() ;
2689         if (static_cast<string>(p) == "2 x ^ 3 + 4 x ^ 2 + x + 1, 5" )
2690             fout_ << ".........PASS!" ;
2691         else
2692         {
2693             fout_ << "\n\tERROR: PolyMod square " << p << " failed." << endl ;
2694             status = false ;
2695         }
2696     }
2697     catch( PolynomialRangeError & e )
2698     {
2699         fout_ << "\n\tERROR:  PolynomialRangeError error [ " << e.what() << " ] " << endl ;
2700         status = false ;
2701     }
2702 
2703     fout_ << "\nTEST:  PolyMod operator* and implicitly, operator*=" ;
2704     try {
2705         Polynomial s( "4x^3 + x^2 + 4, 5" ) ;
2706         Polynomial t( "3x^2 + x + 2, 5" ) ;
2707         Polynomial f( "x^4 + x^2 + 2x + 3, 5" ) ;
2708 
2709         PolyMod smodf( s, f ) ;
2710         PolyMod tmodf( t, f ) ;
2711 
2712         PolyMod p = smodf * tmodf ;
2713         if (static_cast<string>(p) == "2 x ^ 3 + 3 x ^ 2 + 4 x + 2, 5" )
2714             fout_ << ".........PASS!" ;
2715         else
2716         {
2717             fout_ << "\n\tERROR: PolyMod operator* " << p << " failed." << endl ;
2718             status = false ;
2719         }
2720     }
2721     catch( PolynomialRangeError & e )
2722     {
2723         fout_ << "\n\tERROR:  PolynomialRangeError error [ " << e.what() << " ] " << endl ;
2724         status = false ;
2725     }
2726 
2727     fout_ << "\nTEST:  PolyMod x_to_power and isInteger()" ;
2728     try {
2729         Polynomial f( "x^4 + x^2 + 2x + 3, 5" ) ;
2730         PolyMod x( "x, 5", f ) ; // g(x) = 0, modulus = 5.
2731 
2732         PolyMod p = power( x, static_cast<BigInt>( 156u ) ) ;
2733         if (static_cast<string>(p) == "3, 5" && p.isInteger())
2734             fout_ << ".........PASS!" ;
2735         else
2736         {
2737             fout_ << "\n\tERROR: PolyMod x_to_power = |" << static_cast<string>(p) << "| failed." << endl ;
2738             status = false ;
2739         }
2740     }
2741     catch( PolynomialRangeError & e )
2742     {
2743         fout_ << "\n\tERROR:  PolynomialRangeError error: [ " << e.what() << " ] " << endl ;
2744         status = false ;
2745     }
2746 
2747     return status ;
2748 }
2749 
2750 
2751 bool UnitTest::unitTestPolynomialOrder()
2752 {
2753     bool status = true ;
2754 
2755     fout_ << "\nTEST:  PolyOrder reduced Q-I matrix" ;
2756     try {
2757         Polynomial f( "x^4 + x^2 + 2x + 3, 5" ) ;
2758         PolyOrder order( f ) ;
2759 
2760         // Get the fully nullity count.  Don't do early out in findNullity().
2761         order.hasMultipleDistinctFactors( false ) ;
2762         string s = order.printQMatrix() ;
2763         string t = "\n(    0   0   0   0 )\n(    0   4   0   0 )\n(    4   0   0   0 )\n(    0   0   4   0 )\n" ;
2764         if (s == t)
2765             fout_ << ".........PASS!" ;
2766         else
2767         {
2768             fout_ << "\n\tERROR: PolyOrder reduced Q-I failed = " << s << endl ;
2769             fout_ << "\n                   true reduced Q-I = " << t << endl ;
2770             status = false ;
2771         }
2772     }
2773     catch( PolynomialRangeError & e )
2774     {
2775         fout_ << "\n\tERROR:  PolynomialRangeError error [ " << e.what() << " ] " << endl ;
2776         status = false ;
2777     }
2778 
2779     fout_ << "\nTEST:  PolyOrder 3 distinct factors out of 4" ;
2780     try {
2781         Polynomial f( "x^4 + 3 x^3 + 3 x^2 + 3 x + 2, 5" ) ;
2782         PolyOrder order( f ) ;
2783 
2784         // Get the fully nullity count.  Don't do early out in findNullity().
2785         bool multipleFactors = order.hasMultipleDistinctFactors( false ) ;
2786         if (multipleFactors && order.getNullity() == 3)
2787             fout_ << ".........PASS!" ;
2788         else
2789         {
2790             fout_ << "\n\tERROR: PolyOrder 3 distinct factors out of 4 failed" << endl ;
2791             fout_ << " f( x ) = " << f << endl ;
2792             fout_ << " nullity = " << order.getNullity() << endl ;
2793             fout_ << "\n    reduced Q-I matrix " << order.printQMatrix() << endl ;
2794             status = false ;
2795         }
2796     }
2797     catch( PolynomialRangeError & e )
2798     {
2799         fout_ << "\n\tERROR:  PolynomialRangeError error [ " << e.what() << " ] " << endl ;
2800         status = false ;
2801     }
2802 
2803     fout_ << "\nTEST:  PolyOrder, reducible polynomial x^3 + 3 mod 5 with 2 distinct factors" ;
2804     try {
2805         Polynomial f( "x^3 + 3, 5" ) ;
2806         PolyOrder order( f ) ;
2807 
2808         // Get the fully nullity count.  Don't do early out in findNullity().
2809         bool multipleFactors = order.hasMultipleDistinctFactors( false ) ;
2810 
2811         if (multipleFactors && order.getNullity() == 2)
2812             fout_ << ".........PASS!" ;
2813         else
2814         {
2815             fout_ << ".........FAIL!" << endl ;
2816             fout_ << "    PolyOrder 2 distinct factors failed" << endl ;
2817             fout_ << "    f( x ) = " << f << endl ;
2818             fout_ << "    nullity = " << order.getNullity() << endl ;
2819             fout_ << "    reduced Q-I matrix " << order.printQMatrix() << endl ;
2820             status = false ;
2821         }
2822     }
2823     catch( PolynomialRangeError & e )
2824     {
2825         fout_ << ".........FAIL!" << endl ;
2826         fout_ << "    PolynomialRangeError [ " << e.what() << " ] " << endl ;
2827         status = false ;
2828     }
2829 
2830     fout_ << "\nTEST:  PolyOrder, irreducible polynomial x^4 + x^2 + 2x + 3 mod 5 (nullity = 1)" ;
2831     try
2832     {
2833         Polynomial f( "x^4 + x^2 + 2x + 3, 5" ) ;
2834         PolyOrder order( f ) ;
2835 
2836         // Get the fully nullity count.  Don't do early out in findNullity().
2837         bool multipleFactors = order.hasMultipleDistinctFactors( false ) ;
2838 
2839         if (multipleFactors == false && order.getNullity() == 1)
2840             fout_ << ".........PASS!" ;
2841         else
2842         {
2843             fout_ << ".........FAIL!" << endl ;
2844             fout_ << "    PolyOrder irreducible" << endl ;
2845             fout_ << "    f( x ) = " << f << endl ;
2846             fout_ << "    nullity = " << order.getNullity() << endl ;
2847             fout_ << "    reduced Q-I matrix " << order.printQMatrix() << endl ;
2848             status = false ;
2849         }
2850     }
2851     catch( PolynomialRangeError & e )
2852     {
2853         fout_ << ".........FAIL!" << endl ;
2854         fout_ << "    PolynomialRangeError: [ " << e.what() << " ] " << endl ;
2855         status = false ;
2856     }
2857 
2858 
2859     fout_ << "\nTEST:  PolyOrder 1 distinct factor 4 times" ;
2860     {
2861         Polynomial f( "x^4 + 4x^3 + x^2 + 4x + 1, 5" ) ;
2862         PolyOrder order( f ) ;
2863 
2864         // Get the fully nullity count.  Don't do early out in findNullity().
2865         bool multipleFactors = order.hasMultipleDistinctFactors( false ) ;
2866         if (multipleFactors == false && order.getNullity() == 1)
2867             fout_ << ".........PASS!" ;
2868         else
2869         {
2870             fout_ << "\n\tERROR: PolyOrder 1 distinct factor 4 times" << endl ;
2871             fout_ << " f( x ) = " << f << endl ;
2872             fout_ << " nullity = " << order.getNullity() << endl ;
2873             fout_ << "\n    reduced Q-I matrix " << order.printQMatrix() << endl ;
2874             status = false ;
2875         }
2876     }
2877 
2878     fout_ << "\nTEST:  PolyOrder orderM()" ;
2879     {
2880         Polynomial f( "x^4 + x^2 + 2x + 3, 5" ) ;
2881         PolyOrder order( f ) ;
2882 
2883         if (order.orderM())
2884             fout_ << ".........PASS!" ;
2885         else
2886         {
2887             fout_ << "\n\tERROR: PolyOrder orderM failed." << endl ;
2888             status = false ;
2889         }
2890     }
2891 
2892     fout_ << "\nTEST:  PolyOrder orderR() is true" ;
2893     {
2894         Polynomial f( "x^4 + x^2 + 2x + 3, 5" ) ;
2895         PolyOrder order( f ) ;
2896 
2897         ppuint a{ order.orderR() } ;
2898         if (a == 3)
2899             fout_ << ".........PASS!" ;
2900         else
2901         {
2902             fout_ << "\n\tERROR: PolyOrder orderR failed." << endl ;
2903             status = false ;
2904         }
2905     }
2906 
2907     fout_ << "\nTEST:  PolyOrder orderR() is false" ;
2908     {
2909         Polynomial f( "x^4 + x + 3, 5" ) ;
2910         PolyOrder order( f ) ;
2911 
2912         ppuint a{ order.orderR() } ;
2913         if (a == 0)
2914             fout_ << ".........PASS!" ;
2915         else
2916         {
2917             fout_ << "\n\tERROR: PolyOrder orderR failed." << endl ;
2918             status = false ;
2919         }
2920     }
2921 
2922     fout_ << "\nTEST:  PolyOrder isPrimitive on non-primitive poly" ;
2923     {
2924         Polynomial f( "x^5 + x + 1, 2" ) ;
2925         PolyOrder order( f ) ;
2926 
2927         bool isPrimitive = order.isPrimitive() ;
2928         if (!isPrimitive)
2929             fout_ << ".........PASS!" ;
2930         else
2931         {
2932             fout_ << "\n\tERROR: PolyOrder isPrimitive on non-primitive poly" << endl ;
2933             fout_ << " f( x ) = " << f << endl ;
2934             status = false ;
2935         }
2936     }
2937 
2938     fout_ << "\nTEST:  PolyOrder isPrimitive on primitive poly" ;
2939     {
2940         Polynomial f( "x^4 + x^2 + 2x + 3, 5" ) ;
2941         PolyOrder order( f ) ;
2942 
2943         bool isPrimitive = order.isPrimitive() ;
2944         if (isPrimitive)
2945             fout_ << ".........PASS!" ;
2946         else
2947         {
2948             fout_ << "\n\tERROR: PolyOrder isPrimitive on primitive poly" << endl ;
2949             fout_ << " f( x ) = " << f << endl ;
2950             status = false ;
2951         }
2952     }
2953 
2954     fout_ << "\nTEST:  PolyOrder isPrimitive on primitive poly, part II" ;
2955     {
2956         Polynomial f0( "x^4+4, 5" ) ;
2957         PolyOrder order( f0 ) ;
2958 
2959         Polynomial f( "x^4 + x^2 + 2x + 3, 5" ) ;
2960         order.resetPolynomial( f ) ;
2961 
2962         bool isPrimitive = order.isPrimitive() ;
2963         if (isPrimitive)
2964             fout_ << ".........PASS!" ;
2965         else
2966         {
2967             fout_ << "\n\tERROR: PolyOrder isPrimitive on primitive poly, part II" << endl ;
2968             fout_ << " f( x ) = " << f << endl ;
2969             status = false ;
2970         }
2971     }
2972 
2973     return status ;
2974 }
2975 
2976 
2977 bool UnitTest::unitTestParser()
2978 {
2979     bool status = true ;
2980 
2981     // Create a parser with parse tables.
2982     string s ;
2983     PolyValue  v ;
2984     PolyParser< PolySymbol, PolyValue > p ;
2985 
2986     fout_ << "\nTEST:  Parsing command line options for test polynomial x^4 + 1, 2 with -s -t and -c options." ;
2987     {
2988         #ifdef DEBUG_PP_FORCE_UNIT_TEST_FAIL
2989             const char * argv[ 5 ] { "Primpoly", "-s", "-t",  "-c", "x^3 + 1, 2" } ;
2990             const Polynomial truePoly( "x^3 + 1", 2 ) ;
2991         #else
2992             const char * argv[ 5 ] { "Primpoly", "-s", "-t",  "-c", "x^4 + 1, 2" } ;
2993             const Polynomial truePoly( "x^4 + 1", 2 ) ;
2994         #endif
2995 
2996         p.parseCommandLine( 5, argv ) ;
2997 
2998         if (p.test_polynomial_for_primitivity_ && p.print_operation_count_ && p.slow_confirm_ &&
2999             !p.list_all_primitive_polynomials_ && !p.print_help_ &&
3000             p.test_polynomial_ == truePoly)
3001         {
3002             fout_ << ".........PASS!" ;
3003         }
3004         else
3005         {
3006             fout_ << ".........FAIL!" << endl ;
3007             fout_ << "    Test polynomial = " << p.test_polynomial_ ; fout_ << " deg = " << p.test_polynomial_.deg() << endl ;
3008             fout_ << "    p = " << p.p << "    n = " << p.n << endl ;
3009             status = false ;
3010         }
3011     }
3012 
3013     fout_ << "\nTEST:  parsing constant 0" ;
3014     {
3015         s = "0" ;
3016         #ifdef DEBUG_PP_FORCE_UNIT_TEST_FAIL
3017         s = "2" ;
3018         #endif
3019         v = p.parse( s ) ;
3020         if (!(v.scalar_ == 2 && (v.f_.size()-1) == 0 && v.f_[0] == 0))
3021         {
3022             fout_ << ".........FAIL!" << endl ;
3023             fout_ << "    parsing input " << s << endl << " value = "  << v << endl ;
3024             status = false ;
3025         }
3026         else
3027             fout_ << ".........PASS!" ;
3028     }
3029 
3030     fout_ << "\nTEST:  parsing polynomial with a specified modulus:  2 x ^ 3 + 3 x + 4, 5" ;
3031     {
3032         #ifdef DEBUG_PP_FORCE_UNIT_TEST_FAIL
3033             s = "2 x ^ 3 + 3 x + 4, 7" ;
3034         #else
3035             s = "2 x ^ 3 + 3 x + 4, 5" ;
3036         #endif
3037         v = p.parse( s ) ;
3038         if (!(v.scalar_ == 5 && (v.f_.size()-1) == 3 && v.f_[0] == 4 && v.f_[1] == 3 && v.f_[2] == 0 && v.f_[3] == 2))
3039         {
3040             fout_ << ".........FAIL!" << endl ;
3041             fout_ << "    parsing input " << s << endl << " value = " << v << endl ;
3042             status = false ;
3043         }
3044         else
3045             fout_ << ".........PASS!" ;
3046     }
3047 
3048     fout_ << "\nTEST:  parsing polynomial 2x without a modulus, which will be defaulted to p=2:  2x" ;
3049     {
3050         s = "2x" ;
3051         #ifdef DEBUG_PP_FORCE_UNIT_TEST_FAIL
3052         s = "2x,3" ;
3053         #endif
3054         v = p.parse( s ) ;
3055         if (!(v.scalar_ == 2 && (v.f_.size()-1) == 1 && v.f_[0] == 0 && v.f_[1] == 2 ))
3056         {
3057             fout_ << ".........FAIL!" << endl ;
3058             fout_ << "    parsing input " << s << endl << " value = " << v << endl ;
3059             status = false ;
3060         }
3061         else
3062             fout_ << ".........PASS!" ;
3063     }
3064 
3065     fout_ << "\nTEST:  parsing bad syntax x 1" ;
3066     try
3067     {
3068         s = "x 1" ;
3069         #ifdef DEBUG_PP_FORCE_UNIT_TEST_FAIL
3070         s = "x+1" ;
3071         #endif
3072         v = p.parse( s ) ;
3073         if (!(v.scalar_ == 0 && (v.f_.size()-1) == 0 &&
3074               v.f_[0] == 0 && v.f_[1] == 2 ))
3075         {
3076             fout_ << ".........FAIL!" << endl ;
3077             fout_ << "    Parser did not throw a parsing error " << endl ;
3078             fout_ << "    while parsing input " << s << endl << " value = " << v << endl ;
3079             status = false ;
3080         }
3081     }
3082     catch( ParserError & e )
3083     {
3084         // Match only the error message.
3085         // The file name and line number where the error occurred may change with different versions of this software.
3086         string trueErrorMessage = "Expecting to see x^ or x or x ^ integer in sentence x 1" ;
3087         if (static_cast<string>(e.what()).find( trueErrorMessage ) == string::npos)
3088         {
3089             fout_ << ".........FAIL!" << endl ;
3090             fout_ << "    Parser correctly threw a parse error exception while parsing " << s << endl << " value = " << v << endl ;
3091             fout_ << "    but the error message was incorrect!  error = |" << e.what() << "|" << endl ;
3092             status = false ;
3093         }
3094         else
3095             fout_ << ".........PASS!" ;
3096     }
3097 
3098     return status ;
3099 }
3100 #endif // SELF_CHECK