home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / pascal / library / dos / toadhall / long / toadtest.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1988-05-24  |  52.4 KB  |  1,590 lines

  1. {TOADTEST.PAS}
  2.  
  3. PROGRAM toadtest;
  4. {$V-}  {relax string parm testing}
  5.  
  6. (*
  7.  Sample program to test some procedures in TOADLONG.INC,
  8.  TOADINT.INC, TOADCONV.INC, and show off the usefulness
  9.  of TOADTIME.INC.
  10.  
  11.  Released for personal or educational use for non-commercial,
  12.  non-profit purposes.
  13.  
  14.  You may freely distribute, upload, download, and use this source code
  15.  (or any portions thereof) for any personal or educational purposes.
  16.  
  17.  You may NOT use any portions of this code (source or compiled)
  18.  in any product or program intended for licensing, sale, rent,
  19.  "Freeware", or for any commercial purpose.
  20.  
  21.  You may NOT divide, separate, delete, or remove any portions of this
  22.  source code for further distribution.
  23.  
  24.  You may NOT publish any portions of this code without a CASE-BY-CASE
  25.  specific release, in writing, from me.
  26.  
  27.  You may NOT remove these restrictions or credits.  If you incorporate
  28.  any portions of this code in your own program, you MUST include the
  29.  following credit text (in visible ASCII characters) in the source and
  30.  object code:
  31.  
  32.    "Includes TOAD HALL Long Integer functions.
  33.     Copyright (c) 1988 David P Kirschbaum"
  34.  
  35. THIS IS NOT PUBLIC DOMAIN CODE!  I RESERVE ALL RIGHTS FOR THIS SOFTWARE!
  36.  
  37.    Copyright (C) 1988 David P Kirschbaum  All Rights Reserved
  38.  
  39.  (I know, not in the TRUE interest of public domain,
  40.  but if you wanna get rich and famous off this hack,
  41.  you're gonna at LEAST have to recode it!
  42.  Else, contact me for a license.)
  43.  
  44.  Contact me via EMail (or worst case, telephone) if you find
  45.  a need for any more long integer-related functions, or (naturally)
  46.  if you find any bugs.  I kinda enjoy tweaking these suckers!
  47.  
  48.  V1.3, May 88
  49.        Broke out unsigned integer functions to TOADINT.INC.
  50.        Broke out power/sqr/sqrt functions to TOADPOWR.INC.
  51.        Broke out integer/real/long conversion functions to TOADCONV.INC
  52.        Converted long comparisons to assembler.
  53.        Added the following procedures/functions:
  54.          Sqr16           A FAST 16-bit integer square (integer result)
  55.          Long_Sqr        Square a long
  56.          Long_Sqrt       Get a long's square root (integer result)
  57.          Sqrt16          Get an integer's square root (integer result)
  58.          Long_Mod        MOD two longs (long result)
  59.          Real_Mod        MOD two reals (real result)
  60.          Unsigned_To_Real Convert an integer to an unsigned real.
  61.          Byte32_Str      Return a long's bits as a string
  62.            and probably more...
  63.  
  64.        I THINK I have all the bugs and logical errors out of the newer
  65.        procedures.  Release 1.2 was inadequately tested (very embarrassing,
  66.        stupid logical errors, lack of clear understanding on DIVs and MULs).
  67.        Still have to clean up uniform setting of global CF and ZF flags.
  68.  
  69.  V1.2, May 88:
  70.        Added the following procedures:
  71.          Long_Mul_I      multiply long by integer
  72.          Long_Div_I      divide long by integer
  73.          Long_Mul        multiply long by long *** seems to work now ***
  74.          Long_Div        divide long by long  *** still broken ***
  75.          AnyNumStr       Return any number (int,real,long) as a string
  76.                          in base 10 or 16 (hex) (function)
  77.          Real_To_Long    convert real to long integer
  78.          long_To_Real    convert long integer to real (function)
  79.          Global Carry
  80.        Tweaked other long procedures a little.
  81.        No reported bugs to date (e.g., no reports at all!)
  82.  
  83.  V1.1:  Vastly improved inline assembler in TOADLONG.INC
  84.         (was doing v1.0 for relaxation and musta been
  85.         REALLY tired to write such Freshman assembler
  86.         (no offense to Freshmen).
  87.         Fixed a logic error in Long_RcR and Long_RcL,
  88.         and a math error (stupid damned signed integers) in long_To_Real.
  89.         Added a bunch more long integer functions in TOADLONG.INC.
  90.         Added some more flashy tests, nicer interface, in TOADTEST.PAS.
  91.         Split out timer stuff to TOADTIME.INC.
  92.  
  93.  
  94.   Many credits to L. David Baldwin, author of INLINE v2.02.  The use of
  95.   this public domain utility for hacking the inline assembler code
  96.   was invaluable!  (Now if he'd only put back the ability to quote a
  97.   character instead of having to use ASCII values!)
  98.  
  99.   David Kirschbaum
  100.   Toad Hall
  101.   kirsch@braggvax.ARPA
  102.   (and in the other world...
  103.     7573 Jennings Lane
  104.     Fayetteville NC  28303 (the howling wilderness of computerdom)
  105.     (919) 868-3471
  106.   )
  107. *)
  108.  
  109. {$I TOADINT.INC   unsigned integer functions with a couple TYPEs }
  110. {$I TOADLONG.INC  long integer functions/procedures }
  111.                   { with some TYPEs, CONSTants, and VARs }
  112. {$I TOADPOWR.INC  sqr,sqrt, power-related functions }
  113. {$I TOADCONV.INC  various conversion utilities }
  114. {$I TOADTIME.INC  same thing here }
  115.  
  116. TYPE
  117.   Str80 = STRING[80];
  118.  
  119. CONST
  120.   CR = #$0D;
  121.   LF = #$0A;
  122.  
  123. VAR Ch :CHAR;
  124.  
  125. PROCEDURE Prompt;
  126.   {Support procedure.  Wait for user's key to continue}
  127.   VAR Ch : CHAR;
  128.   BEGIN
  129.     WRITE(LF, 'Press any key to continue: ');
  130.     REPEAT UNTIL KeyPressed;  READ(Kbd,Ch);
  131.     WRITELN(LF);
  132.   END;  {of Prompt}
  133.  
  134.  
  135. FUNCTION Tab(col : INTEGER) : Str80;
  136.   {Figure current line position, build a string of spaces
  137.    long enough to fill to col.  Just for pretty displays.
  138.   }
  139.   VAR
  140.     x : INTEGER;
  141.     Temp : Str80;
  142.   BEGIN
  143.     FillChar(Temp,81,' ');              {fill a string with blanks}
  144.     x := WhereX;
  145.     IF col > x THEN x := col - x        {distance to col}
  146.     ELSE x := 0;                        {0 length}
  147.     Temp[0] := CHR(x);                  {force string length}
  148.     Tab := Temp;
  149.   END;  {of Tab}
  150.  
  151.  
  152. PROCEDURE Do_End(N2,T2 : Str80);
  153.   {Support function.  Common elapsed time, final result display}
  154.   BEGIN
  155.     GotoXY(44,whereY);
  156.     WRITELN(N2, Tab(60), T2);           {elapsed time}
  157.   END;  {of Do_End}
  158.  
  159.  
  160. PROCEDURE Test_Date_Time;
  161.   BEGIN
  162.     WRITELN('Date and Time String Test:');
  163.     Date;
  164.     WRITELN('DateStr: [', DateStr, ']');
  165.     Time;
  166.     WRITELN('TimeStr: [', TimeStr, ']');
  167.     Prompt;
  168.   END;  {of Test_Date_Time}
  169.  
  170.  
  171. PROCEDURE Test_Long_Add_Long;
  172.   {Add long to long}
  173.   VAR
  174.     i,j : INTEGER;
  175.     long1,long2 : long_int;
  176.     T1  : STRING[20];
  177.   BEGIN
  178.     Zero_Long(long1);                   {initialize a working long int}
  179.     Make_Long(0,100, long2);
  180.  
  181.     WRITE('Long + Long Add',
  182.           Tab(28), AnyNum_Str(long1, longtyp),
  183.           Tab(45), 'Running...' );
  184.  
  185.     Time;                               {update global time variables}
  186.  
  187.     FOR i := 1 TO MAXINT DO
  188.       FOR j := 1 TO 2 DO                {twice for Kb}
  189.         Long_Add(long1,long2);          {long + long}
  190.     FOR j := 1 TO 2 DO
  191.       Long_Add(long1,long2);            {correct MAXINT shortage}
  192.     long2.lo := 1;                      {a wee little add}
  193.     Long_Add(long1,long2);              {make it obvious}
  194.  
  195.     T1 := Now;                          {remember elapsed time}
  196.     Do_End(AnyNum_Str(long1, longtyp),T1); {display final results}
  197.   END;  {of Test_Long_Add_Long}
  198.  
  199.  
  200. PROCEDURE Test_Real_Add_Real;
  201.   {Same numbers as Test_Long_Add_Long, to let you compare
  202.    elapsed times and results.
  203.   }
  204.   VAR
  205.     i,j   : INTEGER;
  206.     r1,r2 : REAL;
  207.     T1    : STRING[20];
  208.   BEGIN
  209.     r1 := 0.0;                          {let's test with reals now}
  210.     r2 := 100.0;
  211.  
  212.     WRITE('Real + Real Add',
  213.           Tab(28), AnyNum_Str(r1,realtyp),
  214.           Tab(45), 'Running');
  215.  
  216.     Time;                               {update global time variables}
  217.  
  218.     FOR i := 1 TO MAXINT DO
  219.       FOR j := 1 TO 2 DO                {twice for Kb}
  220.         r1 := r1 + r2;                  {real + real}
  221.     FOR j := 1 TO 2 DO
  222.       r1 := r1 + r2;                    {correct MAXINT shortage}
  223.     r2 := 1.0;                          {a wee little add}
  224.     r1 := r1 + r2;                      {make it obvious}
  225.  
  226.     T1 := Now;                          {remember time}
  227.     Do_End(AnyNum_Str(r1, realtyp),T1); {display final results}
  228.   END;  {of Test_Real_Add_Real}
  229.  
  230.  
  231. PROCEDURE Test_Long_Add_Integer;
  232.   {Adding big numbers real fast, but not so intuitively obvious
  233.    it's working right!
  234.   }
  235.   VAR
  236.     i,j   : INTEGER;
  237.     long1 : long_int;
  238.     T1    : STRING[20];
  239.   BEGIN
  240.     Zero_Long(long1);                   {initialize a working long int}
  241.     WRITE('Long + Integer Add',
  242.           Tab(28), AnyNum_Str(long1,longtyp),
  243.           Tab(45), 'Running...');
  244.  
  245.     Time;                               {update global time variables}
  246.  
  247.     FOR i := 1 TO MAXINT DO
  248.       FOR j := 1 TO 2 DO                {twice for Kb}
  249.         Long_Add_I(long1,100);          {long + integer}
  250.     FOR j := 1 TO 2 DO
  251.       Long_Add_I(long1,100);            {correct MAXINT shortage}
  252.     Long_Add_I(long1,1);                {a wee little add}
  253.  
  254.     T1 := Now;                          {remember elapsed time}
  255.     Do_End(AnyNum_Str(long1, longtyp),T1);  {display final results}
  256.   END;  {of Test_Long_Add_Integer}
  257.  
  258.  
  259. PROCEDURE Test_Real_Add_Integer;
  260.   {Same numbers as Test_Long_Add_Integer_2, to let you compare
  261.    elapsed times and (!) results (!).
  262.   }
  263.   VAR
  264.     i,j : INTEGER;
  265.     r   : REAL;
  266.     T1  : STRING[20];
  267.   BEGIN
  268.     r := 0.0;                           {let's test with reals now}
  269.     WRITE('Real + Integer Add',
  270.           Tab(28), AnyNum_Str(r, realtyp),
  271.           Tab(45), 'Running...');
  272.  
  273.     Time;                               {update global time variables}
  274.  
  275.     FOR i := 1 TO MAXINT DO
  276.       FOR j := 1 TO 2 DO                {twice for Kb}
  277.         r := r + 100;                   {real + integer}
  278.     FOR j := 1 TO 2 DO
  279.       r := r + 100;                     {correct MAXINT shortage}
  280.     r := r + 1.0;                       {a wee little add}
  281.  
  282.     T1 := Now;                          {remember time}
  283.     Do_End(AnyNum_Str(r,realtyp),T1);   {display final results}
  284.   END;  {of Test_Real_Add_Integer}
  285.  
  286.  
  287. PROCEDURE Test_Long_Inc;
  288.   {Same numbers, but we're just gonna increment the long int.}
  289.   VAR
  290.     i,j   : INTEGER;
  291.     long1 : long_int;
  292.     T1    : STRING[20];
  293.   BEGIN
  294.     Make_Long(1,0, long1);              {start with a nice big number}
  295.  
  296.     WRITE('Increment Long',
  297.           Tab(28), AnyNum_Str(long1, longtyp),
  298.           Tab(45), 'Running...');
  299.  
  300.     Time;                               {update global time variables}
  301.  
  302.     FOR i := 1 TO MAXINT DO
  303.       FOR j := 1 TO 2 DO                {twice for Kb}
  304.         Long_inc(long1);                {increment long}
  305.     FOR j := 1 TO 3 DO
  306.       Long_inc(long1);                  {correct MAXINT shortage, +1}
  307.  
  308.     T1 := Now;                          {remember expended time}
  309.     Do_End(AnyNum_Str(long1,longtyp),T1);  {display final results}
  310.   END;  {of Test_Long_Inc}
  311.  
  312.  
  313. PROCEDURE Test_Real_Inc;
  314.   {Same numbers, but we're just gonna increment the real.}
  315.   VAR
  316.     i,j   : INTEGER;
  317.     long1 : long_int;
  318.     r     : REAL;
  319.     T1    : STRING[20];
  320.   BEGIN
  321.     Make_Long(1,0, long1);              {start with a nice big number}
  322.     r := long_To_Real(long1);           {insure we have same number}
  323.  
  324.     WRITE('Increment Real',
  325.           Tab(28), AnyNum_Str(r, realtyp),
  326.           Tab(45), 'Running...');
  327.  
  328.     Time;                               {update global time variables}
  329.  
  330.     FOR i := 1 TO MAXINT DO
  331.       FOR j := 1 TO 2 DO                {twice for Kb}
  332.         r := r + 1.0;                   {increment real}
  333.     FOR j := 1 TO 3 DO
  334.       r := r + 1.0;                     {correct MAXINT error, +1}
  335.  
  336.     T1 := Now;                          {remember expended time}
  337.     Do_End(AnyNum_Str(r, realtyp),T1);  {display final results}
  338.   END;  {of Test_Real_Inc}
  339.  
  340.  
  341. PROCEDURE Test_Long_Dec;
  342.   {Same numbers, but we're just gonna decrement the long int.}
  343.   VAR
  344.     i,j   : INTEGER;
  345.     long1 : long_int;
  346.     T1    : STRING[20];
  347.   BEGIN
  348.     Make_Long($FFFF,0, long1);          {start with a nice big number}
  349.  
  350.     WRITE('Decrement Long',
  351.           Tab(28), AnyNum_Str(long1, longtyp),
  352.          Tab(45), 'Running...');
  353.  
  354.     Time;                               {update global time variables}
  355.  
  356.     FOR i := 1 TO MAXINT DO
  357.       FOR j := 1 TO 2 DO                {twice for Kb}
  358.         Long_dec(long1);                {decrement long}
  359.     FOR j := 1 TO 3 DO
  360.       Long_dec(long1);                  {correct MAXINT shortage, -1}
  361.  
  362.     T1 := Now;                          {remember expended time}
  363.     Do_End(AnyNum_Str(long1, longtyp),T1);  {display final results}
  364.   END;  {of Test_Long_Dec}
  365.  
  366.  
  367. PROCEDURE Test_Real_Dec;
  368.   {Same numbers, but we're just gonna decrement the real.}
  369.   VAR
  370.     i,j   : INTEGER;
  371.     long1 : long_int;
  372.     r     : REAL;
  373.     T1    : STRING[20];
  374.   BEGIN
  375.     Make_Long($FFFF,0, long1);          {start with a nice big number}
  376.     r := long_To_Real(long1);           {insure we have same number}
  377.  
  378.     WRITE('Decrement Real',
  379.           Tab(28), AnyNum_Str(r,realtyp),
  380.           Tab(45), 'Running...');
  381.  
  382.     Time;                               {update global time variables}
  383.  
  384.     FOR i := 1 TO MAXINT DO
  385.       FOR j := 1 TO 2 DO                {twice for Kb}
  386.         r := r - 1.0;                   {decrement real}
  387.     FOR j := 1 TO 3 DO
  388.       r := r - 1.0;                     {correct MAXINT error, -1}
  389.  
  390.     T1 := Now;                          {remember expended time}
  391.     Do_End(AnyNum_Str(r, realtyp),T1);  {display final results}
  392.   END;  {of Test_Real_Dec}
  393.  
  394.  
  395. PROCEDURE Test_Long_Mul_Integer;
  396.   {Multiply long * integer.
  397.    We can't blindly do nr := nr * INT too often, or even the REALs
  398.    will overflow!  For this reason, we just multiply our long
  399.    by the loop counter.
  400.   }
  401.   VAR
  402.     i,j   : INTEGER;
  403.     long1,
  404.     long2 : long_int;
  405.     T1    : STRING[20];
  406.   BEGIN
  407.     Make_Long(0,8,long1);               {init a multiplicand}
  408.  
  409.     WRITE('Long * Integer Mul',
  410.           Tab(28), AnyNum_Str(long1, longtyp),
  411.           Tab(45), 'Running...');
  412.  
  413.     Time;                               {update global time variables}
  414.  
  415.     FOR i := 1 TO 2500 DO BEGIN         {stretch our test time}
  416.       long2 := long1;                   {refresh working multiplicand}
  417.       FOR j := 1 TO 8 DO BEGIN
  418.         Long_Mul_I(long2,7);            {long * integer}
  419.         IF CF THEN Writeln(' !OVERFLOW! ');
  420.       END;
  421.     END;
  422.  
  423.     T1 := Now;                          {remember elapsed time}
  424.     Do_End(AnyNum_Str(long2, longtyp),T1); {display final results}
  425.   END;  {of Test_Long_Mul_Integer}
  426.  
  427.  
  428. PROCEDURE Test_Real_Mul_Integer;
  429.   {Same numbers as Test_Long_Mul_Integer, to let you compare
  430.    elapsed times and (!) results (!).
  431.    We can't blindly multiply nr := nr * integer too often, or even the REALs
  432.    will overflow!  For this reason, we just multiply our real by a constant
  433.    in an inner loop.
  434.   }
  435.   VAR
  436.     i,j   : INTEGER;
  437.     r1,r2 : REAL;
  438.     long1 : long_int;
  439.     T1    : STRING[20];
  440.   BEGIN
  441.     r1 := 8.0;                          {initialize a multiplicand}
  442.  
  443.     WRITE('Real * Integer Mul',
  444.           Tab(28), AnyNum_Str(r1, realtyp),
  445.           Tab(45), 'Running...');
  446.  
  447.     Time;                               {update global time variables}
  448.  
  449.     FOR i := 1 TO 2500 DO BEGIN         {stretch our test time}
  450.       r2 := r1;                         {refresh working multiplicand}
  451.       FOR j := 1 TO 8 DO BEGIN
  452.         r2 := r2 * 7;                   {real * integer}
  453.         IF CF THEN ;                    {keep time test fair}
  454.       END;
  455.     END;
  456.  
  457.     T1 := Now;                          {remember time}
  458.     Do_End(AnyNum_Str(r2, realtyp),T1); {display final results}
  459.   END;  {of Test_Real_Mul_Integer}
  460.  
  461.  
  462. PROCEDURE Test_Long_Mul_Long;
  463.   {Multiplying long * long.
  464.    We can't blindly do nr := nr * nr too often, or even the REALs
  465.    will overflow!
  466.   }
  467.   VAR
  468.     i,j    : INTEGER;
  469.     long1,
  470.     long2,
  471.     long3  : long_int;
  472.     T1     : STRING[20];
  473.   BEGIN
  474.     Make_Long(0,8,long1);               {long multiplicand}
  475.     Make_Long(0,7,long2);               {long multiplier}
  476.  
  477.     WRITE('Long * Long Mul',
  478.           Tab(28), AnyNum_Str(long1, longtyp),
  479.           Tab(45), 'Running...');
  480.  
  481.     Time;                               {update global time variables}
  482.  
  483.     FOR i := 1 TO 2500 DO BEGIN         {stretch out test time}
  484.       long3 := long1;                   {refresh long multiplicand}
  485.       FOR j := 1 TO 8 DO BEGIN
  486.         Long_Mul(long3,long2);          {long * long}
  487.         IF CF THEN Writeln(' !Overflow Error!');
  488.       END;
  489.     END;
  490.  
  491.     T1 := Now;                          {remember elapsed time}
  492.     Do_End(AnyNum_Str(long3, longtyp),T1);  {display final results}
  493.   END;  {of Test_Long_Mul_Long}
  494.  
  495.  
  496. PROCEDURE Test_Real_Mul_Real;
  497.   {Same numbers as Test_Long_Mul_Long, to let you compare
  498.    elapsed times and (!) results (!).
  499.    We can't blindly multiply nr := nr * nr too often, or even the REALs
  500.    will overflow!
  501.   }
  502.   VAR
  503.     i,j      : INTEGER;
  504.     r1,r2,r3 : REAL;
  505.     T1       : STRING[20];
  506.   BEGIN
  507.     r1 := 8.0;                          {real multiplicand "constant" }
  508.     r2 := 7.0;                          {real multiplier}
  509.  
  510.     WRITE('Real * Real Mul',
  511.           Tab(28), AnyNum_Str(r1, realtyp),
  512.           Tab(45), 'Running...');
  513.  
  514.     Time;                               {update global time variables}
  515.  
  516.     FOR i := 1 TO 2500 DO BEGIN         {stretch out test time}
  517.       r3 := r1;                         {refresh working dividend}
  518.       FOR j := 1 TO 8 DO BEGIN
  519.         r3 := r3 * r2;                  {real * real}
  520.         IF CF THEN ;                    {keep time test fair}
  521.       END;
  522.     END;
  523.  
  524.     T1 := Now;                          {remember time}
  525.     Do_End(AnyNum_Str(r3, realtyp),T1); {display final results}
  526.   END;  {of Test_Real_Mul_Real}
  527.  
  528.  
  529. PROCEDURE Test_Long_Div_Integer;
  530.   {Dividing long integer by integer.
  531.    Can't blindly do a nr := nr divided by INT too long, or even the REALs
  532.    will overflow or get a DIV 0 problem.  For this reason, we just divide
  533.    a nice big long by the loop counter.
  534.   }
  535.   VAR
  536.     i,j   : INTEGER;
  537.     long1,
  538.     long2 : long_int;
  539.     T1    : STRING[20];
  540.   BEGIN
  541.     Make_Long($FFFF,$FFFE,long1);       {make a working dividend}
  542.  
  543.     WRITE('Long / Integer Div',
  544.           Tab(28), AnyNum_Str(long1, longtyp),
  545.           Tab(45), 'Running...');
  546.  
  547.     Time;                               {update global time variables}
  548.  
  549.     FOR i := 1 TO 2500 DO BEGIN         {stretch our test time}
  550.       long2 := long1;                   {refresh our working dividend}
  551.       FOR j := 1 TO 9 DO BEGIN
  552.         Long_Div_I(long2,7);            {long / integer}
  553.         IF CF THEN Writeln(' !OVERFLOW! ');
  554.       END;
  555.     END;
  556.  
  557.     T1 := Now;                          {remember elapsed time}
  558.     Do_End(AnyNum_Str(long2, longtyp), T1);   {display final results}
  559.   END;  {of Test_Long_Div_Integer}
  560.  
  561.  
  562. PROCEDURE Test_Real_Div_Integer;
  563.   {Same numbers as Test_Long_Div_Integer, to let you compare
  564.    elapsed times and (!) results (!).
  565.    Can't blindly do a nr := nr divided by INT too long, or even the REALs
  566.    will overflow or get a DIV 0 problem.  For this reason, we just divide
  567.    a nice big REAL by the loop counter.
  568.   }
  569.   VAR
  570.     i,j   : INTEGER;
  571.     long1 : long_int;
  572.     r1,r2 : REAL;
  573.     T1    : STRING[20];
  574.   BEGIN
  575.     Make_Long($FFFF,$FFFE,long1);       {make a working dividend}
  576.     r1 := long_To_Real(long1);          {insure we have same number}
  577.  
  578.     WRITE('Real / Integer Div',
  579.            Tab(28), AnyNum_Str(r1, realtyp),
  580.            Tab(45), 'Running...');
  581.  
  582.     Time;                               {update global time variables}
  583.  
  584.     FOR i := 1 TO 2500 DO BEGIN         {stretch our test time}
  585.       r2 := r1;                         {refresh working real dividend}
  586.       FOR j := 1 TO 9 DO BEGIN
  587.         r2 := r2 / 7;                   {real / integer}
  588.         IF CF THEN;                     {keep time test fair}
  589.       END;
  590.     END;
  591.  
  592.     T1 := Now;                          {remember time}
  593.     Do_End(AnyNum_Str(r2, realtyp), T1);{display final results}
  594.   END;  {of Test_Real_Div_Integer}
  595.  
  596.  
  597. PROCEDURE Test_Long_Div_Long;
  598.   {Dividing big numbers (long / long).
  599.    We can't blindly do nr := nr / nr too often, or even the REALs
  600.    will overflow or get a DIV 0 error!  For this reason, we just
  601.    divide our long by a long loop counter.
  602.   }
  603.   VAR
  604.     i,j,k : INTEGER;
  605.     long1,
  606.     long2,
  607.     long3  : long_int;
  608.     T1     : STRING[20];
  609.   BEGIN
  610.     Make_Long($FFFF,$FFFE,long1);       {long dividend}
  611.     Make_Long(0,7,long2);               {long divisor}
  612.  
  613.     WRITE('Long / Long Div',
  614.           Tab(28), AnyNum_Str(long1, longtyp),
  615.           Tab(45), 'Running...');
  616.  
  617.     Time;                               {update global time variables}
  618.  
  619.     FOR i := 1 TO 2500 DO BEGIN         {stretch out test time}
  620.       long3 := long1;                   {refresh working dividend}
  621.       FOR j := 1 TO 9 DO BEGIN
  622.         Long_Div(long3,long2);          {long / long}
  623.         IF CF THEN Writeln(' !OVERFLOW! ');
  624.       END;
  625.     END;
  626.  
  627.     T1 := Now;                          {remember elapsed time}
  628.     Do_End(AnyNum_Str(long3, longtyp),T1);  {display final results}
  629.   END;  {of Test_Long_Div_Long}
  630.  
  631.  
  632. PROCEDURE Test_Real_Div_Real;
  633.   {Same numbers as Test_Long_Div_Long, to let you compare
  634.    elapsed times and (!) results (!).
  635.    We can't blindly divide nr := nr / nr too often, or even the REALs
  636.    will overflow or get a DIV 0 error!  For this reason, we just
  637.    divide our real by the loop counter.
  638.   }
  639.   VAR
  640.     i,j      : INTEGER;
  641.     r1,r2,r3 : REAL;
  642.     long1    : long_int;
  643.     T1       : STRING[20];
  644.   BEGIN
  645.     Make_Long($FFFF,$FFFE,long1);       {long dividend}
  646.     r1 := long_To_Real(long1);          {insure we have same number}
  647.  
  648.     WRITE('Real / Real Div',
  649.           Tab(28), AnyNum_Str(r1, realtyp),
  650.           Tab(45), 'Running...');
  651.  
  652.     Time;                               {update global time variables}
  653.  
  654.     FOR i := 1 TO 2500 DO BEGIN         {stretch out test time}
  655.       r3 := r1;                         {refresh working dividend}
  656.       FOR j := 1 TO 9 DO BEGIN
  657.         r3 := r3 / 7.0;                 {real / real}
  658.         IF CF THEN;                     {keep time test fair}
  659.       END;
  660.     END;
  661.  
  662.     T1 := Now;                          {remember time}
  663.     Do_End(AnyNum_Str(r3, realtyp),T1); {display final results}
  664.   END;  {of Test_Real_Div_Real}
  665.  
  666.  
  667. PROCEDURE Test_Int_Sqr;
  668.   {Test the built-in Turbo square function with an INTEGER}
  669.   VAR
  670.     i,j,k,l: INTEGER;
  671.     T1     : STRING[20];
  672.   BEGIN
  673.     l := 3;                             {a likely number to square}
  674.  
  675.     WRITE('Integer Sqr (Turbo)',
  676.           Tab(28), AnyNum_Str(l, inttyp),
  677.           Tab(45), 'Running...');
  678.  
  679.     Time;                               {update global time variables}
  680.  
  681.     FOR i := 1 TO 10000 DO BEGIN        {stretch out test time}
  682.       k := l;                           {refresh our integer}
  683.       FOR j := 1 TO 4 DO BEGIN
  684.         k := Sqr(k);                    {integer square}
  685.         IF CF THEN;                     {keep time test fair}
  686.       END;
  687.     END;
  688.  
  689.     T1 := Now;                          {remember time}
  690.     Do_End(AnyNum_Str(k, inttyp),T1);   {display final results}
  691.   END;  {of Test_Int_Sqr}
  692.  
  693. PROCEDURE Test_Sqr32;
  694.   {Test the sqr32 procedure (product is long int)}
  695.   VAR
  696.     i,j : INTEGER;
  697.     long1,
  698.     long2 : long_int;
  699.     T1    : STRING[20];
  700.   BEGIN
  701.     Make_Long(0,3,long1);               {long1.lo = a likely integer to square}
  702.  
  703.     WRITE('Sqr32',
  704.           Tab(28), AnyNum_Str(long1.lo, inttyp),
  705.           Tab(45), 'Running...');
  706.  
  707.     Time;                               {update global time variables}
  708.  
  709.     FOR i := 1 TO 10000 DO BEGIN        {stretch out test time}
  710.       long2 := long1;                   {refresh our long2.lo int,
  711.                                          clear long2.hi}
  712.       FOR j := 1 TO 4 DO BEGIN
  713.         Sqr32(long2.lo,long2);          {square int, product in long2}
  714.         IF CF THEN Writeln(' !OVERFLOW! ');
  715.       END;
  716.     END;
  717.  
  718.     T1 := Now;                          {remember time}
  719.     Do_End(AnyNum_Str(long2, longtyp),T1); {display final results}
  720.   END;  {of Test_Sqr32}
  721.  
  722. PROCEDURE Test_Long_Sqr;
  723.   {Test the long square procedure}
  724.   VAR
  725.     i,j    : INTEGER;
  726.     long1,
  727.     long2  : long_int;
  728.     T1     : STRING[20];
  729.   BEGIN
  730.     Make_Long(0,3,long1);               {a likely number to square}
  731.  
  732.     WRITE('Long    Sqr',
  733.           Tab(28), AnyNum_Str(long1, longtyp),
  734.           Tab(45), 'Running...');
  735.  
  736.     Time;                               {update global time variables}
  737.  
  738.     FOR i := 1 TO 10000 DO BEGIN        {stretch out test time}
  739.       long2 := long1;                   {refresh our long}
  740.       FOR j := 1 TO 4 DO BEGIN
  741.         Long_Sqr(long2);                {long square}
  742.         IF CF THEN Writeln(' !OVERFLOW! ');
  743.       END;
  744.     END;
  745.  
  746.     T1 := Now;                          {remember time}
  747.     Do_End(AnyNum_Str(long2, longtyp),T1); {display final results}
  748.   END;  {of Test_Long_Sqr}
  749.  
  750. PROCEDURE Test_Real_Sqr;
  751.   {Test the built-in Turbo square function with REALs}
  752.   VAR
  753.     i,j    : INTEGER;
  754.     r1,r2  : REAL;
  755.     T1     : STRING[20];
  756.   BEGIN
  757.     r1 := 3.0;                          {a likely number to square}
  758.  
  759.     WRITE('Real    Sqr (Turbo)',
  760.           Tab(28), AnyNum_Str(r1, realtyp),
  761.           Tab(45), 'Running...');
  762.  
  763.     Time;                               {update global time variables}
  764.  
  765.     FOR i := 1 TO 10000 DO BEGIN        {stretch out test time}
  766.       r2 := r1;                         {refresh our real}
  767.       FOR j := 1 TO 4 DO BEGIN
  768.         r2 := Sqr(r2);                  {real square}
  769.         IF CF THEN;                     {keep time test fair}
  770.       END;
  771.     END;
  772.  
  773.     T1 := Now;                          {remember time}
  774.     Do_End(AnyNum_Str(r2, realtyp),T1); {display final results}
  775. (* If you wish to examine the actual REAL result
  776.    (including decimal points), enable this:
  777.  
  778. Write('The actual real: ', r2:10:10);
  779. *)
  780.   END;  {of Test_Real_Sqr}
  781.  
  782.  
  783. PROCEDURE Test_Int_Sqrt16;
  784.   {Test our integer square root function Sqrt16}
  785.   VAR
  786.     i,j,
  787.     k,l : INTEGER;
  788.     r   : REAL;
  789.     T1  : STRING[20];
  790.   BEGIN
  791.     k := 81*81;                         {a likely square 3^4 = 81^2}
  792.  
  793.     WRITE('Integer Sqrt16',
  794.           Tab(28), AnyNum_Str(k, inttyp),
  795.           Tab(45), 'Running...');
  796.  
  797.     Time;                               {update global time variables}
  798.  
  799.     FOR i := 1 TO 3333 DO BEGIN         {stretch out test time}
  800.       l := k;                           {refresh integer square}
  801.       FOR j := 1 TO 3 DO                {from 6561 down to 3}
  802.         l := Sqrt16(l);                 {integer square root => integer}
  803.     END;
  804.  
  805.     T1 := Now;                          {remember time}
  806.     Do_End(AnyNum_Str(l, inttyp),T1); {display final results}
  807.   END;  {of Test_Int_Sqrt}
  808.  
  809. PROCEDURE Test_Real_Sqrt;
  810.   {Test the built-in Turbo square root function
  811.    (which returns a REAL), which we convert to an integer.
  812.   }
  813.   VAR
  814.     i,j,k,l: INTEGER;
  815.     r      : REAL;
  816.     T1     : STRING[20];
  817.   BEGIN
  818.     k := 81*81;                         {a likely square 3^4 = 81^2}
  819.  
  820.     WRITE('Integer Sqrt (Turbo)',
  821.           Tab(28), AnyNum_Str(k, inttyp),
  822.           Tab(45), 'Running..a REAL slug!');
  823.  
  824.     Time;                               {update global time variables}
  825.  
  826.     FOR i := 1 TO 3333 DO BEGIN         {stretch out test time}
  827.       l := k;                           {refresh integer square}
  828.       FOR j := 1 TO 3 DO                {from 6561 down to 3}
  829.         l := TRUNC(Sqrt(l));            {integer square root => real => int}
  830.     END;
  831.  
  832.     T1 := Now;                          {remember time}
  833.     Do_End(AnyNum_Str(l, inttyp),T1);   {display final results}
  834. (* If you wish to examine the actual REAL result
  835.    (including decimal points), enable this:
  836.  
  837. l := k;
  838. FOR j := 1 TO 3 DO BEGIN
  839.   r := Sqrt(l);
  840.   l := TRUNC(r);
  841. END;
  842. Write('The actual real: ', r:10:10);
  843. *)
  844.   END;  {of Test_Real_Sqrt}
  845.  
  846.  
  847. PROCEDURE Test_Long_Sqrt_Int;
  848.   {Test the long square root function, using values > 65535}
  849.   VAR
  850.     i,j    : INTEGER;
  851.     long1,
  852.     long2  : long_int;
  853.     T1     : STRING[20];
  854.   BEGIN
  855.     Make_Long($0290,$D741,long1);       {an unlikely square, 81^4}
  856.  
  857.     WRITE('Long    Sqrt',
  858.           Tab(28), AnyNum_Str(long1, longtyp),
  859.           Tab(45), 'Running...');
  860.  
  861.     Time;                               {update global time variables}
  862.  
  863.     FOR i := 1 TO 2500 DO BEGIN         {stretch out test time}
  864.       long2 := long1;                   {refresh our square}
  865.       FOR j := 1 TO 4 DO BEGIN          {from 65536 down to 2}
  866.         long2.lo := Long_Sqrt(long2);   {long square root => integer}
  867.         long2.hi := 0;                  {artificial, but for testing...}
  868.       END;
  869.     END;
  870.  
  871.     T1 := Now;                          {remember time}
  872.     Do_End(AnyNum_Str(long2, longtyp),T1); {display final results}
  873.   END;  {of Test_Long_Sqrt_Int}
  874.  
  875. PROCEDURE Test_Real_Sqrt_Real;
  876.   {Test the built-in Turbo square root function
  877.    (which returns a REAL)
  878.   }
  879.   VAR
  880.     i,j    : INTEGER;
  881.     long1  : long_int;
  882.     r1,r2  : REAL;
  883.     T1     : STRING[20];
  884.   BEGIN
  885.     Make_Long($0290,$D741,long1);       {an unlikely square, 81^4}
  886.     r1 := long_To_Real(long1);          {insure we have same number}
  887.  
  888.     WRITE('Real    Sqrt (Turbo)',
  889.           Tab(28), AnyNum_Str(r1, realtyp),
  890.           Tab(45), 'Running..a REAL slug!');
  891.  
  892.     Time;                               {update global time variables}
  893.  
  894.     FOR i := 1 TO 2500 DO BEGIN         {stretch out test time}
  895.       r2 := r1;                         {refresh our square}
  896.       FOR j := 1 TO 4 DO BEGIN          {from 65536 down to 2}
  897.         r2 := Sqrt(r2);                 {real square root}
  898.         long1.hi := 0;                  {keep it honest}
  899.       END;
  900.     END;
  901.  
  902.     T1 := Now;                          {remember time}
  903.     Do_End(AnyNum_Str(r2, realtyp),T1); {display final results}
  904. (* If you wish to examine the actual REAL result
  905.    (including decimal points), enable this:
  906.  
  907. Write('The actual real: ', r2:10:10);
  908. *)
  909.   END;  {of Test_Real_Sqrt_Real}
  910.  
  911.  
  912. PROCEDURE Test_Long_Mod;
  913.   {Long modulus}
  914.   VAR
  915.     i,j    : INTEGER;
  916.     long1,
  917.     long2,
  918.     long3  : long_int;
  919.     T1     : STRING[20];
  920.   BEGIN
  921.     Make_Long(20,1,long1);              {long dividend}
  922.     Make_Long(10,0,long2);              {long divisor}
  923.  
  924.     WRITELN('Long Modulus',
  925.           Tab(28), AnyNum_Str(long1, longtyp));
  926.     WRITE(Tab(24), 'mod ',
  927.           AnyNum_Str(long2, longtyp),
  928.           Tab(45), 'Running...');
  929.  
  930.     Time;                               {update global time variables}
  931.  
  932.     FOR i := 1 TO 10000 DO BEGIN        {stretch out test time}
  933.       Long_Mod(long1,long2,long3);      {long mod => long3}
  934.       IF CF THEN Writeln(' !OVERFLOW! ');
  935.     END;
  936.  
  937.     T1 := Now;                          {remember elapsed time}
  938.     Do_End(AnyNum_Str(long3, longtyp),T1);  {display final results}
  939.   END;  {of Test_Long_Mod}
  940.  
  941.  
  942. PROCEDURE Test_Real_Mod;
  943.   {Same numbers as Test_Long_Mod, to let you compare
  944.    elapsed times and (!) results (!).
  945.    You can't really use MOD with REALs, so we must do it the hard way.
  946.   }
  947.   VAR
  948.     i,j      : INTEGER;
  949.     r1,r2,r3 : REAL;
  950.     long1,long2 : long_int;
  951.     S1,
  952.     T1       : STRING[20];
  953.   BEGIN
  954.     Make_Long(20,1,long1);              {long dividend}
  955.     Make_Long(10,0,long2);              {long divisor}
  956.  
  957.     r1 := long_To_Real(long1);          {insure we have same number}
  958.     r2 := long_To_Real(long2);
  959.  
  960.     WRITELN('Real Modulus',
  961.           Tab(28), AnyNum_Str(r1, realtyp));
  962.     WRITE(Tab(24),'mod ',
  963.           AnyNum_Str(r2, realtyp),
  964.           Tab(45), 'Running...');
  965.  
  966.     Time;                               {update global time variables}
  967.  
  968.     FOR i := 1 TO 10000 DO BEGIN        {stretch out test time}
  969.       r3 := real_Mod(r1,r2);            {a function in TOADCONV.INC}
  970.       IF CF THEN;                       {keep it honest}
  971.     END;
  972.  
  973.     T1 := Now;                          {remember time}
  974.     Do_End(AnyNum_Str(r3, realtyp),T1); {display final results}
  975. END;  {of Test_Real_Mod}
  976.  
  977.  
  978. PROCEDURE Long_vs_Real;
  979.   {The next tests have timers built in, remember final values,
  980.    etc., so you can get a comparison of elapsed time and accuracy
  981.    between adding really big numbers with long ints and Reals.
  982.   }
  983.   BEGIN
  984.     WRITELN('Speed and accuracy competition between Toadlongs');
  985.     WRITELN('and Turbo Reals, in the following math tests:');
  986.     WRITELN('Long := Long + Long  vs  Real := Real + Real');
  987.     WRITELN('Long := Long + Int   vs  Real := Real + Int');
  988.     WRITELN('Long := SUCC(Long)   vs  Real := Real + 1');
  989.     WRITELN('Long := PRED(Long)   vs  Real := Real - 1');
  990.     WRITELN('Long := Long * Int   vs  Real := Real * Int');
  991.     WRITELN('Long := Long / Int   vs  Real := Real / Int');
  992.     WRITELN('Long := Long * Long  vs  Real := Real * Real');
  993.     WRITELN('Long := Long / Long  vs  Real := Real / Real');
  994.     WRITELN('Long := Sqr(Int)     vs');
  995.     WRITELN('Long := Sqr(Long)   and  Real := Sqr(Real)');
  996.     WRITELN('                    and  Int  := Sqr(Int)');
  997.     WRITELN('Int  := Sqrt16(Int)  vs  Real := Sqrt(Int)');
  998.     WRITELN('Int  := Sqrt32(Long) vs  Real := Sqrt(Real)');
  999.     WRITELN('Long := Long MOD Long vs Real := Real MOD Real');
  1000.     WRITELN(LF, 'Fairly large loops are being used to');
  1001.     WRITELN('provide some significant times and differences.');
  1002.     WRITELN(LF,'Start the competition when ready.');
  1003.     Prompt;
  1004.  
  1005. WRITELN(
  1006. '    Test', Tab(28), 'Orig value', Tab(44), 'Final Value',
  1007. Tab(60), 'Elapsed Time');
  1008.     radix := 16;               {display in Hex}
  1009. (*
  1010.     Test_Long_Add_Long;        {add long to long}
  1011.     Test_Real_Add_Real;        {add real to real}
  1012.     Test_Long_Add_Integer;     {add integer to long}
  1013.     Test_Real_Add_Integer;     {add integer to real}
  1014.     Writeln;
  1015.     Test_Long_Inc;             {long increments}
  1016.     Test_Real_Inc;             {real increments}
  1017.     Test_Long_Dec;             {long decrements}
  1018.     Test_Real_Dec;             {real decrements}
  1019.     Prompt;                    {let him read the results}
  1020.  
  1021.     Test_Long_Mul_Integer;     {long multiplication}
  1022.     Test_Real_Mul_Integer;     {real multiplication}
  1023.     Test_Long_Mul_Long;        {long multiplication}
  1024.     Test_Real_Mul_Real;        {real multiplication}
  1025.     Writeln;
  1026.     Test_Long_Div_Integer;     {long division}
  1027.     Test_Real_Div_Integer;     {real division}
  1028.     Test_Long_Div_Long;        {long division}
  1029.     Test_Real_Div_Real;        {real division}
  1030.     Prompt;                    {let him read the results}
  1031. *)
  1032.     Test_Int_Sqr;              {integer square => integer}
  1033.     Test_Sqr32;                {integer square => long}
  1034.     Test_Long_Sqr;             {long square => long}
  1035.     Test_Real_Sqr;             {real square => real}
  1036.     Writeln;
  1037.     Test_Int_Sqrt16;           {integer square root => integer}
  1038.     Test_Real_Sqrt;            {Normal Turbo sqrt function => real => integer}
  1039.     Writeln;
  1040.  
  1041.     Test_Long_Sqrt_Int;        {long square root => integer}
  1042.     Test_Real_Sqrt_Real;       {Normal Turbo sqrt function w/reals}
  1043.     Prompt;                    {let him read the results}
  1044.  
  1045.     Test_Long_Mod;             {long modulus}
  1046.     Test_Real_Mod;             {real modulus, the hard way}
  1047.     Prompt;                    {let him read the results}
  1048.   END;  {of Long_vs_Real}
  1049.  
  1050.  
  1051. {The next require binary (bit-level) display functions}
  1052.  
  1053. PROCEDURE Test_Long_Add_Integer_1;
  1054.   {Adding not so very big numbers, but intuitively obvious it works.}
  1055.   VAR
  1056.     i,loop  : INTEGER;
  1057.     long1   : long_int;
  1058.     T1      : STRING[20];
  1059.     Ch      : CHAR;
  1060.     Visible : BOOLEAN;
  1061.   BEGIN
  1062.     WRITELN(LF, 'Long Add Integer Test:', LF);
  1063.     WRITELN('Incrementing a long integer by 1024.');
  1064.     WRITELN('Enter V for a Visual display (1000 loops, long screen dumps),');
  1065.     WRITELN('or any other key for a speed run');
  1066.     WRITELN('(', MAXINT, ' loops to give a measurable time).');
  1067.  
  1068.     WRITE('Enter "V" for visual, or any other key for speed run: ');
  1069.     REPEAT UNTIL Keypressed;
  1070.     READ(Kbd,Ch);
  1071.     Visible := (Ch IN ['V','v']);
  1072.     WRITELN;
  1073.  
  1074.     Zero_Long(long1);
  1075.  
  1076.     IF Visible THEN loop := 1000 ELSE BEGIN
  1077.       loop := MAXINT;                   {make it kinda big}
  1078.       WRITELN(LF,
  1079. '    Test', Tab(28), 'Orig value', Tab(44), 'Final Value',
  1080. Tab(60), 'Elapsed Time');
  1081.  
  1082.     WRITE('Long + Integer Add',
  1083.           Tab(28), LHex(long1),
  1084.           Tab(44), 'Running...' );
  1085.       Time;                             {update timer values}
  1086.     END;
  1087.  
  1088.     FOR i := 1 TO loop DO BEGIN
  1089.       Long_Add_I(long1, 1024);          {do the add}
  1090.       IF Visible THEN BEGIN
  1091.         WRITE(i:3, '[', LHex(long1), 'H] ');
  1092.         IF i MOD 5 = 0 THEN WRITELN;    {wrap around}
  1093.       END;
  1094.     END;
  1095.  
  1096.     T1 := Now;                          {remember elapsed time}
  1097.     IF Visible THEN WRITELN
  1098.     ELSE Do_End(LHex(long1), T1);       {display final results}
  1099.  
  1100.     Prompt;
  1101.   END;  {of Test_Long_Add_Integer_1}
  1102.  
  1103.  
  1104. PROCEDURE Test_Long_ShL;
  1105.   {Shows 32-bit Shift Left via visual display so you can watch
  1106.    the patterns flow.
  1107.   }
  1108.   VAR
  1109.     i     : INTEGER;
  1110.     long1 : long_int;
  1111.   BEGIN
  1112.     WRITELN(LF, 'Long Shift Left Test:', LF);
  1113.     long1 := LONG_ONE;
  1114.     WRITELN('Start ', LHex(long1), ' ',
  1115.             LHex(long1), ' ', Byte32_Str(long1), LF );
  1116.  
  1117.     FOR i := 1 TO 31 DO BEGIN
  1118.       WRITE(i:3, ' = ', LHex(long1) , ' ');      {hit, }
  1119.       Long_ShL(long1,1);                         {shift, }
  1120.       WRITELN(LHex(long1), ' ',
  1121.               Byte32_Str(long1) );
  1122.     END;                                         {rotate! (joke)}
  1123.     Prompt;
  1124.   END;  {of Test_Long_ShL}
  1125.  
  1126.  
  1127. PROCEDURE Test_Long_ShR;
  1128.   {Same as Shift Left, but in the other direction.}
  1129.   VAR
  1130.     i     : INTEGER;
  1131.     long1 : long_int;
  1132.   BEGIN
  1133.     WRITELN(LF, 'Long Shift Right Test:', LF);
  1134.     Make_Long($8000,0, long1);
  1135.     WRITELN('Start ', LHex(long1), ' ',
  1136.             LHex(long1), ' ', Byte32_Str(long1) , LF);
  1137.  
  1138.     FOR i := 1 TO 31 DO BEGIN
  1139.       WRITE(i:3, ' = ', LHex(long1) , ' ');      {hit, }
  1140.       Long_ShR(long1,1);                         {shift, }
  1141.       WRITELN(LHex(long1), ' ',
  1142.               Byte32_Str(long1) );
  1143.     END;                                         {rotate! (joke)}
  1144.     Prompt;
  1145.   END;  {of Test_Long_ShR}
  1146.  
  1147.  
  1148. PROCEDURE Test_Long_RcL;
  1149.   {32-bit Rotate Carry Left.
  1150.    In a Rotate Carry, the bits falling off the end are expected
  1151.    to drop into the "flags" carry register, and the "flags" carry
  1152.    be stuffed into the other end.  Got a little tricky with double registers.
  1153.   }
  1154.   VAR
  1155.     i     : INTEGER;
  1156.     long1 : long_int;
  1157.   BEGIN
  1158.     WRITELN(LF, 'Long RcL Test:', LF);
  1159.  
  1160.     i := (1 + 4 + 16 + 64 + 256) ShL 4;         {set some pattern}
  1161.     Make_Long(i,i,long1);                       { in both words}
  1162.  
  1163.     WRITELN('Start ', LHex(long1), ' ',
  1164.             LHex(long1), ' ', Byte32_Str(long1) );
  1165.  
  1166.     Clc;                                        {function in TOADLONG.INC
  1167.                                                  to clear our carry flag}
  1168.     FOR i := 1 TO 31 DO BEGIN
  1169.       WRITE(i:3, ' = ', LHex(long1) , ' ');     {hit, }
  1170.       Long_RcL(long1,1);                        {RcL, }
  1171.       WRITELN(LHex(long1), ' ',
  1172.               Byte32_Str(long1) );
  1173.     END;                                        {rotate! (joke)}
  1174.     Prompt;
  1175.   END;  {of Test_Long_RcL}
  1176.  
  1177.  
  1178. PROCEDURE Test_Long_RcR;
  1179.   {32-bit Rotate Carry Right, again with bits falling off the right
  1180.    coming back in as "flags" to the "high" bit on the left.
  1181.   }
  1182.   VAR
  1183.     i     : INTEGER;
  1184.     long1 : long_int;
  1185.   BEGIN
  1186.     WRITELN(LF, 'Long RcR Test:', LF);
  1187.  
  1188.     i := 1 + 4 + 16 + 64 + 256;                 {make a pretty pattern}
  1189.     Make_Long(i,i,long1);                       { in both words}
  1190.  
  1191.     WRITELN('Start ', LHex(long1), ' ',
  1192.             LHex(long1), ' ', Byte32_Str(long1) );
  1193.  
  1194.     Clc;                                        {function in TOADLONG.INC
  1195.                                                  to clear our carry flag}
  1196.     FOR i := 1 TO 31 DO BEGIN
  1197.       WRITE(i:3, ' = ', LHex(long1) , ' ');     {hit, }
  1198.       Long_RcR(long1,1);                        {RcR, }
  1199.       WRITELN(LHex(long1), ' ',
  1200.               Byte32_Str(long1) );
  1201.     END;                                        {rotate! (joke)}
  1202.     Prompt;
  1203.   END;  {of Test_Long_RcR}
  1204.  
  1205.  
  1206. PROCEDURE Test_Long_Cmp;
  1207.   {Perform extensive tests on the long integer "Cmp"
  1208.    relational operators.
  1209.   }
  1210.     CONST  {some likely typed long integer constants}
  1211.       LONG_0         : long_int = (Lo:0     ; Hi:0);
  1212.       LONG_1         : long_int = (Lo:1     ; Hi:0);
  1213.       LONG_MAXINT    : long_int = (Lo:MAXINT; Hi:0);
  1214.       LONG_MAXINT1   : long_int = (Lo:$8000 ; Hi:0);     {MAXINT+1}
  1215.       LONG_HIMAXINT  : long_int = (Lo:0     ; Hi:MAXINT);
  1216.       LONG_HIMAXINT1 : long_int = (Lo:0     ; Hi:$8000); {MAXINT+1}
  1217.  
  1218. (* Some other longs you may wish to play with:
  1219.       LONG_256  : long_int = (Lo:256 ; Hi:0);
  1220.       LONG_65K  : long_int = (Lo:1024; Hi:1);  {got that, right?}
  1221.       LONG_256K : long_int = (Lo:0   ; Hi:4);  {so you obviously got this}
  1222. *)
  1223.       OpStr : ARRAY[Rel_Op] OF STRING[7] =  {for testing}
  1224.         ('Eq (= )', 'Gt (> )', 'Lt (< )', 'Ne (<>)', 'Ge (>=)', 'Le (<=)');
  1225.  
  1226. (* Enable the following if you wish to pass INTEGER parameters
  1227.   PROCEDURE Cmp_Test(hi1,lo1, hi2,lo2 : INTEGER);
  1228. *)
  1229. (* Enable the following if you wish to pass long integer parameters *)
  1230.   PROCEDURE Cmp_Test(VAR long1,long2 : long_int);
  1231.  
  1232.     {common 32-bit long int relational operators.
  1233.      Long constants are explained/defined in TOADLONG.INC.
  1234.     }
  1235.     VAR
  1236. (* Enable the following if you're passing INTEGER parameters
  1237.       long1,long2 : long_int;
  1238. *)
  1239.       N1,N2 : STRING[20];
  1240.       op : Rel_Op;  {defined in TOADLONG.INC}
  1241.     BEGIN
  1242.       WRITELN(LF, 'Long Integer Relational Operator Tests:',LF);
  1243. (* Enable the following if you're passing INTEGER parameters
  1244.       Make_Long(hi1,lo1, long1);
  1245.       Make_Long(hi2,lo2, long2);
  1246. *)
  1247.       LStr_Hex(long1, N1);   {make some long integer hex strings}
  1248.       LStr_Hex(long2, N2);
  1249.  
  1250.       Writeln(
  1251. {
  1252.      0000:0000 cmp 0000:0000  0000:0000 cmp 0000:0000  0000:0000 cmp 0000:0000
  1253. }
  1254. '    ', N1,  ' cmp ', N2,  '  ', N2,  ' cmp ', N1,  '  ', N1,  ' cmp ', N1);
  1255.       FOR op := Eq TO Le DO
  1256.         WRITELN(OpStr[op], ': ',
  1257.                 Tab(15), Long_Cmp(long1, op, long2),
  1258.                 Tab(40), Long_Cmp(long2, op, long1),
  1259.                 Tab(65), Long_Cmp(long1, op, long1) );
  1260.       Prompt;
  1261.     END;  {of Cmp_Test}
  1262.  
  1263.   BEGIN  {Test_Long_Cmp}
  1264. (* You can pass long integer parameters as integers to a function or procedure
  1265.    (in this case, Cmp_Test just above, letting Cmp_Test build the long integers
  1266.    itself) ...
  1267.     Cmp_Test(0,1, 0,0);
  1268.     Cmp_Test(0,MAXINT+1, 0,MAXINT);
  1269.     Cmp_Test(MAXINT+1,0, MAXINT,0);
  1270. *)
  1271. (* Or you can pass long integers themselves to a function or procedure:
  1272. *)
  1273.    Cmp_Test(LONG_1, LONG_0);
  1274.    Cmp_Test(LONG_MAXINT1, LONG_MAXINT);
  1275.    Cmp_Test(LONG_HIMAXINT1, LONG_HIMAXINT);
  1276.  
  1277.   END;  {of Test_Long_Cmp}
  1278.  
  1279.  
  1280. (******** Long NOT Testing ********)
  1281.  
  1282. PROCEDURE Test_Long_Not;
  1283.   {Test our Long_Not procedure and its sister Long_Not_Test
  1284.    boolean function.
  1285.   }
  1286.   VAR long1 : long_int;
  1287.  
  1288.   PROCEDURE Not_Test(local1 : long_int);
  1289.     {NOT the long int local1, then test it against the NOT product.
  1290.      Notice in the procedure line above that you do NOT have to declare
  1291.      local1 a VAR ("VAR local1 : long_int").
  1292.      However, WARNING!  Turbo is passing an address to local 1 as the
  1293.      parameter, NOT the actual record itself.  In other words, Turbo is
  1294.      still acting EXACTLY as if you had said "VAR local1"!
  1295.      local1 is going to be changed by ANYTHING you do to it here!
  1296.      Don't forget that!  It bit me BIG TIME until I got used to it.
  1297.     }
  1298.     VAR
  1299.       localNot : long_int;
  1300.       Boo      : BOOLEAN;
  1301.     BEGIN
  1302.       Long_Not(local1, localNot);               {first get a NOTted long
  1303.                                                  localNot := local1 NOT local1}
  1304.       Boo := Long_Not_Test(local1, localNot);   {test for NOTted match}
  1305.  
  1306.       Writeln(
  1307. 'Original long    NOTted long    Is it NOT?    long - 1    Is it NOT?');
  1308.       Write(LHex(local1),
  1309.             '        ', LHex(localNot),
  1310.             '      ', Boo);
  1311.  
  1312.       Long_Dec(local1);                         {change the long a bit}
  1313.       Boo := Long_Not_Test(local1, localNot);   {do the test again}
  1314.       Writeln('          ',LHex(local1),
  1315.               '   ', Boo);
  1316.     END;  {of Not_Test}
  1317.  
  1318.  
  1319.   BEGIN   {Test_Long_Not}
  1320.     WRITELN(LF, 'Long NOT and NOT NOT Tests:',LF);
  1321.  
  1322.     Make_Long(0,0, long1);     Not_Test(long1);
  1323.     Make_Long(0,1, long1);     Not_Test(long1);
  1324.     Make_Long($FF,0, long1);   Not_Test(long1);
  1325.     Make_Long($FF,$FF, long1); Not_Test(long1);
  1326.  
  1327.     Prompt;
  1328.   END;  {of Test_Long_Not}
  1329.  
  1330.  
  1331. PROCEDURE Test_Long_Xor;
  1332.   {Long integer Exclusive Or test}
  1333.   VAR
  1334.     long1, long2 : long_int;
  1335.     N0, N1, N2, N3 : Str12;
  1336.   BEGIN
  1337.     WRITELN(LF, 'Long Xor Test:', LF);
  1338.     Make_Long(64,64, long1);            {create a constant for XORing}
  1339.     LStr_Hex(long1, N0);                {remember it}
  1340.  
  1341.     long2.hi := (1 + 4 + 16 + 64 + 256) ShL 4;  {set some pattern}
  1342.     long2.lo := long2.hi;
  1343.     LStr_Hex(long2, N1);                {Remember original value}
  1344.  
  1345.  
  1346.   { long2 := long2 XOR long1 }
  1347.     Long_Xor(long2, long1);             {first get an XORed long}
  1348.     LStr_Hex(long2, N2);                {remember first XORed value}
  1349.  
  1350.     Long_Xor(long2, long1);             {XOR it with same value}
  1351.     LStr_Hex(long2, N3);                {(answer should be same as original)}
  1352.  
  1353.     Writeln(
  1354. 'Original long     XORed with      XORed long      XORed again');
  1355.     WRITELN('  ', N1,
  1356.             '       ', N0,
  1357.             '       ', N2,
  1358.             '       ', N3 );
  1359.  
  1360.     Long_Xor(long2, long2);             {should produce a 0}
  1361.     LStr_Hex(long2, N1);                {remember product}
  1362.     Long_Xor(long2, long2);
  1363.     LStr_Hex(long2, N2);                {remember product}
  1364.  
  1365.     Writeln('  ', N3,
  1366.             '       ', N3,
  1367.             '       ', N1,
  1368.             '       ', N2 );
  1369.     Prompt;
  1370.  
  1371.   END;  {of Test_Long_Xor}
  1372.  
  1373.  
  1374. PROCEDURE Test_Long_Mul_Integer_1;
  1375.   {v1.3 Multiplying not so very big numbers, but intuitively obvious it works.}
  1376.   VAR
  1377.     i,loop  : INTEGER;
  1378.     long1   : long_int;
  1379.     T1      : STRING[20];
  1380.     Ch      : CHAR;
  1381.     Visible : BOOLEAN;
  1382.   BEGIN
  1383.     WRITELN(LF, 'Long * Integer Multiply Test:', LF);
  1384.     WRITELN('Multiplying a long integer by 2.');
  1385.     WRITELN('Enter V for a Visual display (1000 loops, long screen dumps),');
  1386.     WRITELN('or any other key for a speed run');
  1387.     WRITELN('(', MAXINT, ' loops to give a measurable time).');
  1388.  
  1389.     WRITE('Enter "V" for visual, or any other key for speed run: ');
  1390.     REPEAT UNTIL Keypressed;
  1391.     READ(Kbd,Ch);
  1392.     Visible := (Ch IN ['V','v']);
  1393.     WRITELN;
  1394.  
  1395.     Make_Long(1,1,long1);  {so long.hi and long.lo both have a value}
  1396.  
  1397.     IF Visible THEN loop := 1000 ELSE BEGIN
  1398.       loop := MAXINT;                   {make it kinda big}
  1399.       WRITELN(LF,
  1400. '    Test', Tab(28), 'Orig value', Tab(44), 'Final Value',
  1401. Tab(60), 'Elapsed Time');
  1402.  
  1403.     WRITE('Long * Integer Multiply',
  1404.           Tab(28), LHex(long1),
  1405.           Tab(44), 'Running...' );
  1406.       Time;                             {update timer values}
  1407.     END;
  1408.  
  1409.     FOR i := 1 TO loop DO BEGIN
  1410.       Long_Mul_I(long1, 2);    {do the multiplication}
  1411.       IF Visible THEN BEGIN
  1412.         WRITE(i:3, '[', LHex(long1), 'H] ');
  1413.         IF i MOD 5 = 0 THEN WRITELN;    {wrap around}
  1414.       END;
  1415.     END;
  1416.  
  1417.     T1 := Now;                          {remember elapsed time}
  1418.     IF Visible THEN WRITELN
  1419.     ELSE Do_End(LHex(long1), T1);       {display final results}
  1420.  
  1421.     Prompt;
  1422.   END;  {of Test_Long_Mul_Integer_1}
  1423.  
  1424.  
  1425. PROCEDURE Test_Long_Div_Integer_1;
  1426.   {v1.3 Dividing not so very big numbers, but intuitively obvious it works.}
  1427.   VAR
  1428.     i,loop  : INTEGER;
  1429.     long1   : long_int;
  1430.     T1      : STRING[20];
  1431.     Ch      : CHAR;
  1432.     Visible : BOOLEAN;
  1433.   BEGIN
  1434.     WRITELN(LF, 'Long / Integer Division Test:', LF);
  1435.     WRITELN('Dividing a long integer by 2.');
  1436.     WRITELN('Enter V for a Visual display (1000 loops, long screen dumps),');
  1437.     WRITELN('or any other key for a speed run');
  1438.     WRITELN('(', MAXINT, ' loops to give a measurable time).');
  1439.  
  1440.     WRITE('Enter "V" for visual, or any other key for speed run: ');
  1441.     REPEAT UNTIL Keypressed;
  1442.     READ(Kbd,Ch);
  1443.     Visible := (Ch IN ['V','v']);
  1444.     WRITELN;
  1445.  
  1446.     Make_Long($FFFF,$FFFF,long1);  {so long.hi and long.lo both have a value}
  1447.  
  1448.     IF Visible THEN loop := 1000 ELSE BEGIN
  1449.       loop := MAXINT;                   {make it kinda big}
  1450.       WRITELN(LF,
  1451. '    Test', Tab(28), 'Orig value', Tab(44), 'Final Value',
  1452. Tab(60), 'Elapsed Time');
  1453.  
  1454.     WRITE('Long * Integer Division',
  1455.           Tab(28), LHex(long1),
  1456.           Tab(44), 'Running...' );
  1457.       Time;                             {update timer values}
  1458.     END;
  1459.  
  1460.     FOR i := 1 TO loop DO BEGIN
  1461.       Long_Div_I(long1, 2);       {do the division}
  1462.       IF Visible THEN BEGIN
  1463.         WRITE(i:3, '[', LHex(long1), 'H] ');
  1464.         IF i MOD 5 = 0 THEN WRITELN;    {wrap around}
  1465.       END;
  1466.     END;
  1467.  
  1468.     T1 := Now;                          {remember elapsed time}
  1469.     IF Visible THEN WRITELN
  1470.     ELSE Do_End(LHex(long1), T1);       {display final results}
  1471.  
  1472.     Prompt;
  1473.   END;  {of Test_Long_Div_Integer_1}
  1474.  
  1475.  
  1476. PROCEDURE Test_LongReal;
  1477.   VAR long : long_int;
  1478.  
  1479.   PROCEDURE Do_Test;
  1480.     VAR
  1481.       long1 : long_int;
  1482.       r     : REAL;
  1483.       L16_1,L16_2,R16,
  1484.       L10_1,L10_2,R10 : STRING[20];
  1485.     BEGIN
  1486.       radix := 16;                              {display the original long}
  1487.       L16_1 := AnyNum_Str(long,longtyp);        {convert to hex string}
  1488.       r     := long_To_Real(long);              {long to real conversion}
  1489.       R16   := AnyNum_Str(r,realtyp);           {convert to hex string}
  1490.       Real_To_Long(r,long1);                    {back to long}
  1491.       L16_2 := AnyNum_Str(long1,longtyp);       {convert to hex string}
  1492.  
  1493.       radix := 10;                              {switch to base 10}
  1494.       L10_1 := AnyNum_Str(long,longtyp);        {convert to base 10 string}
  1495.       R10   := AnyNum_Str(r,realtyp);           {convert to base 10 string}
  1496.       L10_2 := AnyNum_Str(long1,longtyp);       {convert to base 10 string}
  1497.  
  1498.       Writeln('long         : ', L16_1, L10_1:20);
  1499.       Writeln(' long to real: ', R16  , R10  :20);
  1500.       Writeln(' real to long: ', L16_2, L10_2:20);
  1501.     END;  {of Do_Test}
  1502.  
  1503.   BEGIN  {Test_LongReal}
  1504.     Writeln('Testing Long <> REAL conversion:');
  1505.  
  1506.     Make_Long(0,1,long);            Do_Test;
  1507.     Make_Long(0,$7FFF,long);        Do_Test;  {tough area around MAXINT}
  1508.     Make_Long(0,$8000,long);        Do_Test;
  1509.     Make_Long(0,$8001,long);        Do_Test;
  1510.     Make_Long(0,$FFFF,long);        Do_Test;
  1511.     Make_Long(1,0,long);            Do_Test;
  1512.     Long_Inc(long);                 Do_Test;
  1513.     Make_Long(MAXINT,0,long);       Do_Test;
  1514.     Make_Long($FFFF,$FFFF, long);   Do_Test;
  1515.     Prompt;
  1516.   END;  {of Test_LongReal}
  1517.  
  1518.  
  1519. PROCEDURE Test_AnyNum_Str;
  1520.   VAR
  1521.     typ : numtype;
  1522.     i : INTEGER;
  1523.     long : long_int;
  1524.  
  1525.   PROCEDURE Do_Test;
  1526.     VAR
  1527.       i : INTEGER;
  1528.       r : REAL;
  1529.     BEGIN
  1530.       r := long_To_Real(long);  {test our long-to-real conversion also}
  1531.       i := long.lo;
  1532.       radix := 16;
  1533.       WRITE('long:',
  1534.             Tab(30), AnyNum_Str(long, longtyp));
  1535.       radix := 10;
  1536.       Writeln(Tab(60), AnyNum_Str(long, longtyp));
  1537.       radix := 16;
  1538.       WRITE('=> real:',
  1539.             Tab(30), AnyNum_Str(r,    realtyp));
  1540.       radix := 10;
  1541.       Writeln(Tab(60), AnyNum_Str(r,    realtyp));
  1542.       radix := 16;
  1543.       WRITE(' => integer:',
  1544.             Tab(30), AnyNum_Str(i,    inttyp ));
  1545.       radix := 10;
  1546.       Writeln(Tab(60), AnyNum_Str(i,    inttyp));
  1547.     END;  {of Do_Test}
  1548.  
  1549.   BEGIN  {Test_AnyNum_Str}
  1550.     Writeln('AnyNum_Str Test:',
  1551.             Tab(40), 'Radix 16',
  1552.             Tab(60), 'Radix 10');
  1553.     Make_Long(0,1,long);          Do_Test;
  1554.     Make_Long(0,$7FFF,long);      Do_Test;  {tough area around MAXINT}
  1555.     Make_Long(0,$8000,long);      Do_Test;
  1556.     Make_Long(0,$8001,long);      Do_Test;
  1557.     Make_Long(0,$FFFF,long);      Do_Test;
  1558.     Make_Long(1,0,long);          Do_Test;
  1559.     Make_Long($FFFF,$FFFF,long);  Do_Test;
  1560.     Prompt;
  1561.   END;  {of Test_AnyNum_Str}
  1562.  
  1563.  
  1564. BEGIN  {ToadTest main}
  1565.  
  1566.   Test_Date_Time;            {system time, date/time strings}
  1567.  
  1568.   Test_AnyNum_Str;           {generic number>string formatting}
  1569.  
  1570.   Test_LongReal;             {long <= => REAL conversion}
  1571.  
  1572.   Long_Vs_Real;              {speed test before boring stuff}
  1573.  
  1574.   Test_Long_Add_Integer_1;   {simple add integer to long int}
  1575.  
  1576.   Test_Long_Cmp;             {long integer relational operator tests}
  1577.  
  1578.   Test_Long_Not;             {long integer NOT function}
  1579.  
  1580.   Test_Long_ShL;             {Long shift/rotate tests}
  1581.   Test_Long_ShR;
  1582.  
  1583.   Test_Long_RcL;
  1584.   Test_Long_RcR;
  1585.  
  1586.   Test_Long_Xor;             {Long exclusive or}
  1587.  
  1588.   WRITELN('Toad Test completed.  Rivvvtt');
  1589. END.
  1590.