gmp 0.4.0-x86-mingw32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG +109 -0
 - data/INSTALL +4 -0
 - data/README.rdoc +357 -0
 - data/benchmark/COPYING +674 -0
 - data/benchmark/README +75 -0
 - data/benchmark/divide +34 -0
 - data/benchmark/gcd +38 -0
 - data/benchmark/gexpr +0 -0
 - data/benchmark/gexpr.c +359 -0
 - data/benchmark/multiply +44 -0
 - data/benchmark/rsa +93 -0
 - data/benchmark/runbench +147 -0
 - data/benchmark/version +1 -0
 - data/ext/extconf.rb +30 -0
 - data/ext/gmp.c +197 -0
 - data/ext/gmpbench_timing.c +80 -0
 - data/ext/gmpf.c +595 -0
 - data/ext/gmpf.h +144 -0
 - data/ext/gmpq.c +780 -0
 - data/ext/gmpq.h +12 -0
 - data/ext/gmprandstate.c +224 -0
 - data/ext/gmpz.c +1968 -0
 - data/ext/gmpz.h +20 -0
 - data/ext/libgmp-10.dll +0 -0
 - data/ext/ruby_gmp.h +243 -0
 - data/ext/takeover.h +36 -0
 - data/manual.pdf +0 -0
 - data/manual.tex +804 -0
 - data/test/README +34 -0
 - data/test/tc_cmp.rb +74 -0
 - data/test/tc_division.rb +109 -0
 - data/test/tc_f_arithmetics_coersion.rb +71 -0
 - data/test/tc_f_precision.rb +48 -0
 - data/test/tc_fib_fac_nextprime.rb +51 -0
 - data/test/tc_floor_ceil_truncate.rb +21 -0
 - data/test/tc_logical_roots.rb +48 -0
 - data/test/tc_q.rb +27 -0
 - data/test/tc_q_basic.rb +41 -0
 - data/test/tc_random.rb +54 -0
 - data/test/tc_sgn_neg_abs.rb +47 -0
 - data/test/tc_swap.rb +19 -0
 - data/test/tc_z.rb +71 -0
 - data/test/tc_z_basic.rb +35 -0
 - data/test/tc_z_exponentiation.rb +22 -0
 - data/test/tc_z_gcd_lcm_invert.rb +57 -0
 - data/test/tc_z_jac_leg_rem.rb +73 -0
 - data/test/tc_z_logic.rb +54 -0
 - data/test/tc_z_shifts_last_bits.rb +22 -0
 - data/test/tc_z_to_d_to_i.rb +24 -0
 - data/test/tc_zerodivisionexceptions.rb +17 -0
 - data/test/test-12.rb +14 -0
 - data/test/test-19.rb +13 -0
 - data/test/test-20.rb +29 -0
 - data/test/test-21.rb +37 -0
 - data/test/test-22.rb +12 -0
 - data/test/test-23.rb +11 -0
 - data/test/test_helper.rb +8 -0
 - data/test/unit_tests.rb +39 -0
 - metadata +115 -0
 
    
        data/benchmark/README
    ADDED
    
    | 
         @@ -0,0 +1,75 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            GMPbench
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            Copyright 2003, 2008 Free Software Foundation, Inc.
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            This file is part of GMPbench.
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
            GMPbench is free software; you can redistribute it and/or modify it
         
     | 
| 
      
 8 
     | 
    
         
            +
            under the terms of the GNU General Public License as published by the Free
         
     | 
| 
      
 9 
     | 
    
         
            +
            Software Foundation; either version 3 of the License, or (at your option)
         
     | 
| 
      
 10 
     | 
    
         
            +
            any later version.
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
            GMPbench is distributed in the hope that it will be useful, but WITHOUT ANY
         
     | 
| 
      
 13 
     | 
    
         
            +
            WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
         
     | 
| 
      
 14 
     | 
    
         
            +
            FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
         
     | 
| 
      
 15 
     | 
    
         
            +
            details.
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
            You should have received a copy of the GNU General Public License along
         
     | 
| 
      
 18 
     | 
    
         
            +
            with the GMPbench.  If not, see http://www.gnu.org/licenses/.
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
            For this version of GMPbench, there are just 6 parts:
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
            	[Multiply large numbers]
         
     | 
| 
      
 24 
     | 
    
         
            +
            	base.multiply (weight 1)
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
            	[Divide numbers of different sizes]
         
     | 
| 
      
 27 
     | 
    
         
            +
            	base.divide (weight 1)
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
            	[Compute the greatest common divisor]
         
     | 
| 
      
 30 
     | 
    
         
            +
            	base.gcd (weight 0.5)
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
            	[Compute the extended greatest common divisor]
         
     | 
| 
      
 33 
     | 
    
         
            +
            	base.gcdext (weight 0.5)
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
            	[Compute the square root]
         
     | 
| 
      
 36 
     | 
    
         
            +
            	base.sqrt (weight 0.5)
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
            	[Compute the nth root]
         
     | 
| 
      
 39 
     | 
    
         
            +
            	base.root (weight 0.5)
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
      
 41 
     | 
    
         
            +
            	[Run the RSA encryption algorithm]
         
     | 
| 
      
 42 
     | 
    
         
            +
            	app.rsa (weight 1)
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
            	[Compute digits of Pi]
         
     | 
| 
      
 45 
     | 
    
         
            +
            	app.pi (weight 1)
         
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
            Result scores are computed as a weighted geometric mean.  Please use the included
         
     | 
| 
      
 49 
     | 
    
         
            +
            script runbench for running the benchmarks and computing benchmark scores.
         
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
      
 51 
     | 
    
         
            +
            Guidelines:
         
     | 
| 
      
 52 
     | 
    
         
            +
             
     | 
| 
      
 53 
     | 
    
         
            +
              1. If benchmark code is changed, results are invalid and should not be
         
     | 
| 
      
 54 
     | 
    
         
            +
                 reported as GMPbench results.  Compilation parameters may be changed,
         
     | 
| 
      
 55 
     | 
    
         
            +
                 as long as the same parameters are used for all GMP source files and
         
     | 
| 
      
 56 
     | 
    
         
            +
                 for all benchmark files.
         
     | 
| 
      
 57 
     | 
    
         
            +
              2. If GMP source is changed, results should not be reported as GMPbench
         
     | 
| 
      
 58 
     | 
    
         
            +
                 results unless the following three conditions are met:
         
     | 
| 
      
 59 
     | 
    
         
            +
                 A. It is clearly stated that GMP was changed when reporting results.
         
     | 
| 
      
 60 
     | 
    
         
            +
                 B. The changes are generic and reasonable and not specifically targeted
         
     | 
| 
      
 61 
     | 
    
         
            +
            	towards improving some aspect specifically exercised by the benchmark
         
     | 
| 
      
 62 
     | 
    
         
            +
            	suite.
         
     | 
| 
      
 63 
     | 
    
         
            +
                 C. All rights to the changes are assigned to the Free Software
         
     | 
| 
      
 64 
     | 
    
         
            +
            	Foundation prior to publication of the benchmark results.
         
     | 
| 
      
 65 
     | 
    
         
            +
              3. As long as these rules are followed, results may be freely used.
         
     | 
| 
      
 66 
     | 
    
         
            +
                 Please also report results to the GMP developer's mailing list
         
     | 
| 
      
 67 
     | 
    
         
            +
                 gmp-devel@swox.com.
         
     | 
| 
      
 68 
     | 
    
         
            +
              4. When reporting results, this data should be included:
         
     | 
| 
      
 69 
     | 
    
         
            +
                 A. Machine type and model
         
     | 
| 
      
 70 
     | 
    
         
            +
                 B. CPU type and clock frequency
         
     | 
| 
      
 71 
     | 
    
         
            +
                 C. GMP version used
         
     | 
| 
      
 72 
     | 
    
         
            +
                 D. List of modifications as permitted above
         
     | 
| 
      
 73 
     | 
    
         
            +
                 E. Compiler and compiler version used
         
     | 
| 
      
 74 
     | 
    
         
            +
                 F. Compiler options used
         
     | 
| 
      
 75 
     | 
    
         
            +
              5. The benchmark suite is believed to be compatible with GMP 4.1 or later.
         
     | 
    
        data/benchmark/divide
    ADDED
    
    | 
         @@ -0,0 +1,34 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            #!/usr/bin/env ruby
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            require '../ext/gmp'
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            dividend = ARGV[0].to_i
         
     | 
| 
      
 6 
     | 
    
         
            +
            divisor = ARGV[1].to_i
         
     | 
| 
      
 7 
     | 
    
         
            +
            random_state = GMP::RandState.new
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
            x = random_state.urandomb(dividend)
         
     | 
| 
      
 10 
     | 
    
         
            +
            y = random_state.urandomb(divisor)
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
            t = GMP::time { z = x.tdiv y }
         
     | 
| 
      
 13 
     | 
    
         
            +
            iterations = (1 + (1e4 / t)).to_i
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
            print "Dividing an %i-bit number by an %i-bit number %i times..." % [dividend, divisor, iterations]
         
     | 
| 
      
 16 
     | 
    
         
            +
            STDOUT.flush
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
            t0 = GMP::cputime
         
     | 
| 
      
 19 
     | 
    
         
            +
            iterations.times do
         
     | 
| 
      
 20 
     | 
    
         
            +
              z = x.tdiv y
         
     | 
| 
      
 21 
     | 
    
         
            +
            end
         
     | 
| 
      
 22 
     | 
    
         
            +
            ti = GMP::cputime - t0
         
     | 
| 
      
 23 
     | 
    
         
            +
              
         
     | 
| 
      
 24 
     | 
    
         
            +
            puts "done!"
         
     | 
| 
      
 25 
     | 
    
         
            +
            ops_per_sec = 1000.0 * iterations / ti
         
     | 
| 
      
 26 
     | 
    
         
            +
            f = 100.0
         
     | 
| 
      
 27 
     | 
    
         
            +
            decimals = 0
         
     | 
| 
      
 28 
     | 
    
         
            +
            while true
         
     | 
| 
      
 29 
     | 
    
         
            +
              decimals += 1
         
     | 
| 
      
 30 
     | 
    
         
            +
              break if ops_per_sec > f
         
     | 
| 
      
 31 
     | 
    
         
            +
              f = f * 0.1
         
     | 
| 
      
 32 
     | 
    
         
            +
            end
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
            puts "RESULT: %#{decimals}f operations per second\n" % ops_per_sec
         
     | 
    
        data/benchmark/gcd
    ADDED
    
    | 
         @@ -0,0 +1,38 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            #!/usr/bin/env ruby
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            require '../ext/gmp'
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            m = ARGV[0].to_i
         
     | 
| 
      
 6 
     | 
    
         
            +
            n = ARGV[1].to_i
         
     | 
| 
      
 7 
     | 
    
         
            +
            random_state = GMP::RandState.new
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
            x = random_state.urandomb(m)
         
     | 
| 
      
 10 
     | 
    
         
            +
            y = random_state.urandomb(n)
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
            print "Calibrating CPU speed..."
         
     | 
| 
      
 13 
     | 
    
         
            +
            STDOUT.flush
         
     | 
| 
      
 14 
     | 
    
         
            +
            t = GMP::time { z = x.gcd(y) }
         
     | 
| 
      
 15 
     | 
    
         
            +
            puts "done"
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
            iterations = (1 + (1e4 / t)).to_i
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
            print "Calculating the gcd of a %i-bit number and a %i-bit number %i times..." % [m, n, iterations]
         
     | 
| 
      
 20 
     | 
    
         
            +
            STDOUT.flush
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
            t0 = GMP::cputime
         
     | 
| 
      
 23 
     | 
    
         
            +
            iterations.times do
         
     | 
| 
      
 24 
     | 
    
         
            +
              z = x.gcd(y)
         
     | 
| 
      
 25 
     | 
    
         
            +
            end
         
     | 
| 
      
 26 
     | 
    
         
            +
            ti = GMP::cputime - t0
         
     | 
| 
      
 27 
     | 
    
         
            +
              
         
     | 
| 
      
 28 
     | 
    
         
            +
            puts "done!"
         
     | 
| 
      
 29 
     | 
    
         
            +
            ops_per_sec = 1000.0 * iterations / ti
         
     | 
| 
      
 30 
     | 
    
         
            +
            f = 100.0
         
     | 
| 
      
 31 
     | 
    
         
            +
            decimals = 0
         
     | 
| 
      
 32 
     | 
    
         
            +
            while true
         
     | 
| 
      
 33 
     | 
    
         
            +
              decimals += 1
         
     | 
| 
      
 34 
     | 
    
         
            +
              break if ops_per_sec > f
         
     | 
| 
      
 35 
     | 
    
         
            +
              f = f * 0.1
         
     | 
| 
      
 36 
     | 
    
         
            +
            end
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
            puts "RESULT: %#{decimals}f operations per second\n" % ops_per_sec
         
     | 
    
        data/benchmark/gexpr
    ADDED
    
    | 
         Binary file 
     | 
    
        data/benchmark/gexpr.c
    ADDED
    
    | 
         @@ -0,0 +1,359 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            /* Expression evaluation using plain floating-point arithmetic.
         
     | 
| 
      
 2 
     | 
    
         
            +
               Copyright 1999, 2000, 2001, 2002, 2003, 2006 Free Software Foundation, Inc.
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            This program is free software; you can redistribute it and/or modify it under
         
     | 
| 
      
 5 
     | 
    
         
            +
            the terms of the GNU General Public License as published by the Free Software
         
     | 
| 
      
 6 
     | 
    
         
            +
            Foundation; either version 2, or (at your option) any later version.
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
            This program is distributed in the hope that it will be useful, but WITHOUT ANY
         
     | 
| 
      
 9 
     | 
    
         
            +
            WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
         
     | 
| 
      
 10 
     | 
    
         
            +
            PARTICULAR PURPOSE.  See the GNU General Public License for more details.
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
            You should have received a copy of the GNU General Public License along with
         
     | 
| 
      
 13 
     | 
    
         
            +
            this program; see the file COPYING.  If not, write to the Free Software
         
     | 
| 
      
 14 
     | 
    
         
            +
            Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.  */
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
            #include <math.h>
         
     | 
| 
      
 17 
     | 
    
         
            +
            #include <ctype.h>
         
     | 
| 
      
 18 
     | 
    
         
            +
            #include <setjmp.h>
         
     | 
| 
      
 19 
     | 
    
         
            +
            #include <stdio.h>
         
     | 
| 
      
 20 
     | 
    
         
            +
            #include <stdlib.h>
         
     | 
| 
      
 21 
     | 
    
         
            +
            #include <string.h>
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
            jmp_buf top;
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
            static char *bp, *expr_start_p, *expr_end_p;
         
     | 
| 
      
 26 
     | 
    
         
            +
            static int ch;
         
     | 
| 
      
 27 
     | 
    
         
            +
            static int previous_result_valid_flag;
         
     | 
| 
      
 28 
     | 
    
         
            +
            double previous_result;
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
            double term (void), expo (void), factor (void), number (void);
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
            #define next skip ()
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
            void
         
     | 
| 
      
 35 
     | 
    
         
            +
            skip (void)
         
     | 
| 
      
 36 
     | 
    
         
            +
            {
         
     | 
| 
      
 37 
     | 
    
         
            +
              do
         
     | 
| 
      
 38 
     | 
    
         
            +
                ch = *bp++;
         
     | 
| 
      
 39 
     | 
    
         
            +
              while (ch == ' ' || ch == '\n');
         
     | 
| 
      
 40 
     | 
    
         
            +
            }
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
            void
         
     | 
| 
      
 43 
     | 
    
         
            +
            error (void)
         
     | 
| 
      
 44 
     | 
    
         
            +
            {
         
     | 
| 
      
 45 
     | 
    
         
            +
              fprintf (stderr, "%s\n", expr_start_p);
         
     | 
| 
      
 46 
     | 
    
         
            +
              fprintf (stderr, "%*s^ syntax error\n", (int) (bp - expr_start_p) - 1, "");
         
     | 
| 
      
 47 
     | 
    
         
            +
              longjmp (top, 1);
         
     | 
| 
      
 48 
     | 
    
         
            +
            }
         
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
      
 50 
     | 
    
         
            +
            double
         
     | 
| 
      
 51 
     | 
    
         
            +
            expr (void)
         
     | 
| 
      
 52 
     | 
    
         
            +
            {
         
     | 
| 
      
 53 
     | 
    
         
            +
              double e;
         
     | 
| 
      
 54 
     | 
    
         
            +
              if (ch == '+')
         
     | 
| 
      
 55 
     | 
    
         
            +
                {
         
     | 
| 
      
 56 
     | 
    
         
            +
                  next;
         
     | 
| 
      
 57 
     | 
    
         
            +
                  e = term ();
         
     | 
| 
      
 58 
     | 
    
         
            +
                }
         
     | 
| 
      
 59 
     | 
    
         
            +
              else if (ch == '-')
         
     | 
| 
      
 60 
     | 
    
         
            +
                {
         
     | 
| 
      
 61 
     | 
    
         
            +
                  next;
         
     | 
| 
      
 62 
     | 
    
         
            +
                  e = - term ();
         
     | 
| 
      
 63 
     | 
    
         
            +
                }
         
     | 
| 
      
 64 
     | 
    
         
            +
              else
         
     | 
| 
      
 65 
     | 
    
         
            +
                e = term ();
         
     | 
| 
      
 66 
     | 
    
         
            +
              while (ch == '+' || ch == '-')
         
     | 
| 
      
 67 
     | 
    
         
            +
                { char op;
         
     | 
| 
      
 68 
     | 
    
         
            +
                  op = ch;
         
     | 
| 
      
 69 
     | 
    
         
            +
                  next;
         
     | 
| 
      
 70 
     | 
    
         
            +
                  if (op == '-')
         
     | 
| 
      
 71 
     | 
    
         
            +
            	e -= term ();
         
     | 
| 
      
 72 
     | 
    
         
            +
                  else
         
     | 
| 
      
 73 
     | 
    
         
            +
            	e += term ();
         
     | 
| 
      
 74 
     | 
    
         
            +
                }
         
     | 
| 
      
 75 
     | 
    
         
            +
              return e;
         
     | 
| 
      
 76 
     | 
    
         
            +
            }
         
     | 
| 
      
 77 
     | 
    
         
            +
             
     | 
| 
      
 78 
     | 
    
         
            +
            double
         
     | 
| 
      
 79 
     | 
    
         
            +
            term (void)
         
     | 
| 
      
 80 
     | 
    
         
            +
            {
         
     | 
| 
      
 81 
     | 
    
         
            +
              double t;
         
     | 
| 
      
 82 
     | 
    
         
            +
              t = expo ();
         
     | 
| 
      
 83 
     | 
    
         
            +
              for (;;)
         
     | 
| 
      
 84 
     | 
    
         
            +
                switch (ch)
         
     | 
| 
      
 85 
     | 
    
         
            +
                  {
         
     | 
| 
      
 86 
     | 
    
         
            +
                  case '*':
         
     | 
| 
      
 87 
     | 
    
         
            +
            	next;
         
     | 
| 
      
 88 
     | 
    
         
            +
            	t *= expo ();
         
     | 
| 
      
 89 
     | 
    
         
            +
            	break;
         
     | 
| 
      
 90 
     | 
    
         
            +
                  case '/':
         
     | 
| 
      
 91 
     | 
    
         
            +
            	next;
         
     | 
| 
      
 92 
     | 
    
         
            +
            	t /= expo ();
         
     | 
| 
      
 93 
     | 
    
         
            +
            	break;
         
     | 
| 
      
 94 
     | 
    
         
            +
                  case '%':
         
     | 
| 
      
 95 
     | 
    
         
            +
            	next;
         
     | 
| 
      
 96 
     | 
    
         
            +
            	t = fmod (t, expo ());
         
     | 
| 
      
 97 
     | 
    
         
            +
            	break;
         
     | 
| 
      
 98 
     | 
    
         
            +
                  default:
         
     | 
| 
      
 99 
     | 
    
         
            +
            	return t;
         
     | 
| 
      
 100 
     | 
    
         
            +
                  }
         
     | 
| 
      
 101 
     | 
    
         
            +
            }
         
     | 
| 
      
 102 
     | 
    
         
            +
             
     | 
| 
      
 103 
     | 
    
         
            +
            double
         
     | 
| 
      
 104 
     | 
    
         
            +
            expo (void)
         
     | 
| 
      
 105 
     | 
    
         
            +
            {
         
     | 
| 
      
 106 
     | 
    
         
            +
              double e;
         
     | 
| 
      
 107 
     | 
    
         
            +
              e = factor ();
         
     | 
| 
      
 108 
     | 
    
         
            +
              if (ch == '^')
         
     | 
| 
      
 109 
     | 
    
         
            +
                {
         
     | 
| 
      
 110 
     | 
    
         
            +
                  next;
         
     | 
| 
      
 111 
     | 
    
         
            +
                  e = pow (e, expo ());
         
     | 
| 
      
 112 
     | 
    
         
            +
                }
         
     | 
| 
      
 113 
     | 
    
         
            +
              return e;
         
     | 
| 
      
 114 
     | 
    
         
            +
            }
         
     | 
| 
      
 115 
     | 
    
         
            +
             
     | 
| 
      
 116 
     | 
    
         
            +
            struct functions
         
     | 
| 
      
 117 
     | 
    
         
            +
            {
         
     | 
| 
      
 118 
     | 
    
         
            +
              char *spelling;
         
     | 
| 
      
 119 
     | 
    
         
            +
              double (* evalfn) ();
         
     | 
| 
      
 120 
     | 
    
         
            +
            };
         
     | 
| 
      
 121 
     | 
    
         
            +
             
     | 
| 
      
 122 
     | 
    
         
            +
            double
         
     | 
| 
      
 123 
     | 
    
         
            +
            my_log2 (double x)
         
     | 
| 
      
 124 
     | 
    
         
            +
            {
         
     | 
| 
      
 125 
     | 
    
         
            +
              return log (x) * 1.4426950408889634073599246810019;
         
     | 
| 
      
 126 
     | 
    
         
            +
            }
         
     | 
| 
      
 127 
     | 
    
         
            +
             
     | 
| 
      
 128 
     | 
    
         
            +
            struct functions fns[] =
         
     | 
| 
      
 129 
     | 
    
         
            +
            {
         
     | 
| 
      
 130 
     | 
    
         
            +
              {"log2", my_log2},
         
     | 
| 
      
 131 
     | 
    
         
            +
              {"log10", log10},
         
     | 
| 
      
 132 
     | 
    
         
            +
              {"log", log},
         
     | 
| 
      
 133 
     | 
    
         
            +
              {"exp", exp},
         
     | 
| 
      
 134 
     | 
    
         
            +
              {"sqrt", sqrt},
         
     | 
| 
      
 135 
     | 
    
         
            +
              {"floor", floor},
         
     | 
| 
      
 136 
     | 
    
         
            +
              {"ceil", ceil},
         
     | 
| 
      
 137 
     | 
    
         
            +
              {"sin", sin},
         
     | 
| 
      
 138 
     | 
    
         
            +
              {"cos", cos},
         
     | 
| 
      
 139 
     | 
    
         
            +
              {"tan", tan},
         
     | 
| 
      
 140 
     | 
    
         
            +
              {"asin", asin},
         
     | 
| 
      
 141 
     | 
    
         
            +
              {"acos", acos},
         
     | 
| 
      
 142 
     | 
    
         
            +
              {"atan", atan},
         
     | 
| 
      
 143 
     | 
    
         
            +
              {"sinh", sinh},
         
     | 
| 
      
 144 
     | 
    
         
            +
              {"cosh", cosh},
         
     | 
| 
      
 145 
     | 
    
         
            +
              {"tanh", tanh},
         
     | 
| 
      
 146 
     | 
    
         
            +
              {"asinh", asinh},
         
     | 
| 
      
 147 
     | 
    
         
            +
              {"acosh", acosh},
         
     | 
| 
      
 148 
     | 
    
         
            +
              {"atanh", atanh},
         
     | 
| 
      
 149 
     | 
    
         
            +
              {0, 0}
         
     | 
| 
      
 150 
     | 
    
         
            +
            };
         
     | 
| 
      
 151 
     | 
    
         
            +
             
     | 
| 
      
 152 
     | 
    
         
            +
             
     | 
| 
      
 153 
     | 
    
         
            +
            double
         
     | 
| 
      
 154 
     | 
    
         
            +
            factor (void)
         
     | 
| 
      
 155 
     | 
    
         
            +
            {
         
     | 
| 
      
 156 
     | 
    
         
            +
              double f;
         
     | 
| 
      
 157 
     | 
    
         
            +
              int i;
         
     | 
| 
      
 158 
     | 
    
         
            +
             
     | 
| 
      
 159 
     | 
    
         
            +
              for (i = 0; fns[i].spelling != 0; i++)
         
     | 
| 
      
 160 
     | 
    
         
            +
                {
         
     | 
| 
      
 161 
     | 
    
         
            +
                  char *spelling = fns[i].spelling;
         
     | 
| 
      
 162 
     | 
    
         
            +
                  int len = strlen (spelling);
         
     | 
| 
      
 163 
     | 
    
         
            +
                  if (strncmp (spelling, bp - 1, len) == 0 && ! isalnum (bp[-1 + len]))
         
     | 
| 
      
 164 
     | 
    
         
            +
            	{
         
     | 
| 
      
 165 
     | 
    
         
            +
            	  bp += len - 1;
         
     | 
| 
      
 166 
     | 
    
         
            +
            	  next;
         
     | 
| 
      
 167 
     | 
    
         
            +
            	  if (ch != '(')
         
     | 
| 
      
 168 
     | 
    
         
            +
            	    error ();
         
     | 
| 
      
 169 
     | 
    
         
            +
            	  next;
         
     | 
| 
      
 170 
     | 
    
         
            +
            	  f = expr ();
         
     | 
| 
      
 171 
     | 
    
         
            +
            	  if (ch != ')')
         
     | 
| 
      
 172 
     | 
    
         
            +
            	    error ();
         
     | 
| 
      
 173 
     | 
    
         
            +
            	  next;
         
     | 
| 
      
 174 
     | 
    
         
            +
            	  return (fns[i].evalfn) (f);
         
     | 
| 
      
 175 
     | 
    
         
            +
            	}
         
     | 
| 
      
 176 
     | 
    
         
            +
                }
         
     | 
| 
      
 177 
     | 
    
         
            +
             
     | 
| 
      
 178 
     | 
    
         
            +
              if (ch == '(')
         
     | 
| 
      
 179 
     | 
    
         
            +
                {
         
     | 
| 
      
 180 
     | 
    
         
            +
                  next;
         
     | 
| 
      
 181 
     | 
    
         
            +
                  f = expr ();
         
     | 
| 
      
 182 
     | 
    
         
            +
                  if (ch == ')')
         
     | 
| 
      
 183 
     | 
    
         
            +
            	next;
         
     | 
| 
      
 184 
     | 
    
         
            +
                  else
         
     | 
| 
      
 185 
     | 
    
         
            +
            	error ();
         
     | 
| 
      
 186 
     | 
    
         
            +
                }
         
     | 
| 
      
 187 
     | 
    
         
            +
              else
         
     | 
| 
      
 188 
     | 
    
         
            +
                f = number ();
         
     | 
| 
      
 189 
     | 
    
         
            +
              if (ch == '!')
         
     | 
| 
      
 190 
     | 
    
         
            +
                {
         
     | 
| 
      
 191 
     | 
    
         
            +
                  unsigned long n;
         
     | 
| 
      
 192 
     | 
    
         
            +
                  if (floor (f) != f)
         
     | 
| 
      
 193 
     | 
    
         
            +
            	error ();
         
     | 
| 
      
 194 
     | 
    
         
            +
                  for (n = f, f = 1; n > 1; n--)
         
     | 
| 
      
 195 
     | 
    
         
            +
            	f *= n;
         
     | 
| 
      
 196 
     | 
    
         
            +
                  next;
         
     | 
| 
      
 197 
     | 
    
         
            +
                }
         
     | 
| 
      
 198 
     | 
    
         
            +
              return f;
         
     | 
| 
      
 199 
     | 
    
         
            +
            }
         
     | 
| 
      
 200 
     | 
    
         
            +
             
     | 
| 
      
 201 
     | 
    
         
            +
            double
         
     | 
| 
      
 202 
     | 
    
         
            +
            number (void)
         
     | 
| 
      
 203 
     | 
    
         
            +
            {
         
     | 
| 
      
 204 
     | 
    
         
            +
              double n;
         
     | 
| 
      
 205 
     | 
    
         
            +
              char *endp;
         
     | 
| 
      
 206 
     | 
    
         
            +
             
     | 
| 
      
 207 
     | 
    
         
            +
              if (strncmp ("pi", bp - 1, 2) == 0 && ! isalnum (bp[1]))
         
     | 
| 
      
 208 
     | 
    
         
            +
                {
         
     | 
| 
      
 209 
     | 
    
         
            +
                  bp += 2 - 1;
         
     | 
| 
      
 210 
     | 
    
         
            +
                  next;
         
     | 
| 
      
 211 
     | 
    
         
            +
                  return 3.1415926535897932384626433832795;
         
     | 
| 
      
 212 
     | 
    
         
            +
                }
         
     | 
| 
      
 213 
     | 
    
         
            +
              if (ch == '$')
         
     | 
| 
      
 214 
     | 
    
         
            +
                {
         
     | 
| 
      
 215 
     | 
    
         
            +
                  if (! previous_result_valid_flag)
         
     | 
| 
      
 216 
     | 
    
         
            +
            	error ();
         
     | 
| 
      
 217 
     | 
    
         
            +
                  next;
         
     | 
| 
      
 218 
     | 
    
         
            +
                  return previous_result;
         
     | 
| 
      
 219 
     | 
    
         
            +
                }
         
     | 
| 
      
 220 
     | 
    
         
            +
              if (ch != '.' && (ch < '0' || ch > '9'))
         
     | 
| 
      
 221 
     | 
    
         
            +
                error ();
         
     | 
| 
      
 222 
     | 
    
         
            +
              n = strtod (bp - 1, &endp);
         
     | 
| 
      
 223 
     | 
    
         
            +
              if (endp == bp - 1)
         
     | 
| 
      
 224 
     | 
    
         
            +
                error ();
         
     | 
| 
      
 225 
     | 
    
         
            +
              bp = endp;
         
     | 
| 
      
 226 
     | 
    
         
            +
              next;
         
     | 
| 
      
 227 
     | 
    
         
            +
              return n;
         
     | 
| 
      
 228 
     | 
    
         
            +
            }
         
     | 
| 
      
 229 
     | 
    
         
            +
             
     | 
| 
      
 230 
     | 
    
         
            +
            int nl_flag = 1;
         
     | 
| 
      
 231 
     | 
    
         
            +
            int hhmm_flag = 0;
         
     | 
| 
      
 232 
     | 
    
         
            +
            int dhhmm_flag = 0;
         
     | 
| 
      
 233 
     | 
    
         
            +
            int round_flag = 0;
         
     | 
| 
      
 234 
     | 
    
         
            +
            int prec = 5;
         
     | 
| 
      
 235 
     | 
    
         
            +
             
     | 
| 
      
 236 
     | 
    
         
            +
            void
         
     | 
| 
      
 237 
     | 
    
         
            +
            output (double exp)
         
     | 
| 
      
 238 
     | 
    
         
            +
            {
         
     | 
| 
      
 239 
     | 
    
         
            +
              int h, m;
         
     | 
| 
      
 240 
     | 
    
         
            +
              if (hhmm_flag)
         
     | 
| 
      
 241 
     | 
    
         
            +
                {
         
     | 
| 
      
 242 
     | 
    
         
            +
                  m = exp * 60;
         
     | 
| 
      
 243 
     | 
    
         
            +
                  h = m / 60;
         
     | 
| 
      
 244 
     | 
    
         
            +
                  m -= h * 60;
         
     | 
| 
      
 245 
     | 
    
         
            +
                  printf ("%02d:%02d", h, m);
         
     | 
| 
      
 246 
     | 
    
         
            +
                }
         
     | 
| 
      
 247 
     | 
    
         
            +
              else if (dhhmm_flag)
         
     | 
| 
      
 248 
     | 
    
         
            +
                {
         
     | 
| 
      
 249 
     | 
    
         
            +
                  int d;
         
     | 
| 
      
 250 
     | 
    
         
            +
                  m = exp * (24 * 60);
         
     | 
| 
      
 251 
     | 
    
         
            +
                  d = m / (24 * 60);
         
     | 
| 
      
 252 
     | 
    
         
            +
                  m -= d * (24 * 60);
         
     | 
| 
      
 253 
     | 
    
         
            +
                  h = m / 60;
         
     | 
| 
      
 254 
     | 
    
         
            +
                  m -= h * 60;
         
     | 
| 
      
 255 
     | 
    
         
            +
                  printf ("%dd %02d:%02d", d, h, m);
         
     | 
| 
      
 256 
     | 
    
         
            +
                }
         
     | 
| 
      
 257 
     | 
    
         
            +
              else
         
     | 
| 
      
 258 
     | 
    
         
            +
                printf ("%.*g", prec, exp);
         
     | 
| 
      
 259 
     | 
    
         
            +
              if (nl_flag)
         
     | 
| 
      
 260 
     | 
    
         
            +
                puts ("");
         
     | 
| 
      
 261 
     | 
    
         
            +
              previous_result = exp;
         
     | 
| 
      
 262 
     | 
    
         
            +
              previous_result_valid_flag = 1;
         
     | 
| 
      
 263 
     | 
    
         
            +
            }
         
     | 
| 
      
 264 
     | 
    
         
            +
             
     | 
| 
      
 265 
     | 
    
         
            +
            int
         
     | 
| 
      
 266 
     | 
    
         
            +
            main (int argc, char **argv)
         
     | 
| 
      
 267 
     | 
    
         
            +
            {
         
     | 
| 
      
 268 
     | 
    
         
            +
              while (argc >= 2)
         
     | 
| 
      
 269 
     | 
    
         
            +
                {
         
     | 
| 
      
 270 
     | 
    
         
            +
                  if (!strcmp (argv[1], "-n"))
         
     | 
| 
      
 271 
     | 
    
         
            +
            	{
         
     | 
| 
      
 272 
     | 
    
         
            +
            	  nl_flag = 0;
         
     | 
| 
      
 273 
     | 
    
         
            +
            	  argv++;
         
     | 
| 
      
 274 
     | 
    
         
            +
            	  argc--;
         
     | 
| 
      
 275 
     | 
    
         
            +
            	}
         
     | 
| 
      
 276 
     | 
    
         
            +
                  else if (!strcmp (argv[1], "-hhmm"))
         
     | 
| 
      
 277 
     | 
    
         
            +
            	{
         
     | 
| 
      
 278 
     | 
    
         
            +
            	  hhmm_flag = 1;
         
     | 
| 
      
 279 
     | 
    
         
            +
            	  argv++;
         
     | 
| 
      
 280 
     | 
    
         
            +
            	  argc--;
         
     | 
| 
      
 281 
     | 
    
         
            +
            	}
         
     | 
| 
      
 282 
     | 
    
         
            +
                  else if (!strcmp (argv[1], "-dhhmm"))
         
     | 
| 
      
 283 
     | 
    
         
            +
            	{
         
     | 
| 
      
 284 
     | 
    
         
            +
            	  dhhmm_flag = 1;
         
     | 
| 
      
 285 
     | 
    
         
            +
            	  argv++;
         
     | 
| 
      
 286 
     | 
    
         
            +
            	  argc--;
         
     | 
| 
      
 287 
     | 
    
         
            +
            	}
         
     | 
| 
      
 288 
     | 
    
         
            +
                  else if (!strcmp (argv[1], "-round"))
         
     | 
| 
      
 289 
     | 
    
         
            +
            	{
         
     | 
| 
      
 290 
     | 
    
         
            +
            	  round_flag = 1;
         
     | 
| 
      
 291 
     | 
    
         
            +
            	  argv++;
         
     | 
| 
      
 292 
     | 
    
         
            +
            	  argc--;
         
     | 
| 
      
 293 
     | 
    
         
            +
            	}
         
     | 
| 
      
 294 
     | 
    
         
            +
                  else if (!strcmp (argv[1], "-prec"))
         
     | 
| 
      
 295 
     | 
    
         
            +
            	{
         
     | 
| 
      
 296 
     | 
    
         
            +
            	  prec = atoi (argv[2]);
         
     | 
| 
      
 297 
     | 
    
         
            +
            	  argv += 2;
         
     | 
| 
      
 298 
     | 
    
         
            +
            	  argc -= 2;
         
     | 
| 
      
 299 
     | 
    
         
            +
            	}
         
     | 
| 
      
 300 
     | 
    
         
            +
                  else if (!strcmp (argv[1], "-help") || !strcmp (argv[1], "-h"))
         
     | 
| 
      
 301 
     | 
    
         
            +
            	{
         
     | 
| 
      
 302 
     | 
    
         
            +
            	  printf ("usage: %s [options] expr [expr ... ]\n", argv[0]);
         
     | 
| 
      
 303 
     | 
    
         
            +
            	  printf ("   options:    -n      -- suppress newline\n");
         
     | 
| 
      
 304 
     | 
    
         
            +
            	  printf ("               -prec n -- print n digits\n");
         
     | 
| 
      
 305 
     | 
    
         
            +
            	  printf ("               -round  -- round to nearest integer\n");
         
     | 
| 
      
 306 
     | 
    
         
            +
            	  printf ("               -hhmm   -- print in base 60 (time format)\n");
         
     | 
| 
      
 307 
     | 
    
         
            +
            	  printf ("               -dhhmm  -- print in base 24,60,60 (time format)\n");
         
     | 
| 
      
 308 
     | 
    
         
            +
            	  printf ("               -help   -- you've figured out that one\n");
         
     | 
| 
      
 309 
     | 
    
         
            +
            	  exit (0);
         
     | 
| 
      
 310 
     | 
    
         
            +
            	}
         
     | 
| 
      
 311 
     | 
    
         
            +
                  else
         
     | 
| 
      
 312 
     | 
    
         
            +
            	break;
         
     | 
| 
      
 313 
     | 
    
         
            +
                }
         
     | 
| 
      
 314 
     | 
    
         
            +
             
     | 
| 
      
 315 
     | 
    
         
            +
              if (argc >= 2)
         
     | 
| 
      
 316 
     | 
    
         
            +
                {
         
     | 
| 
      
 317 
     | 
    
         
            +
                  int i;
         
     | 
| 
      
 318 
     | 
    
         
            +
                  double exp;
         
     | 
| 
      
 319 
     | 
    
         
            +
             
     | 
| 
      
 320 
     | 
    
         
            +
                  for (i = 1; i < argc; i++)
         
     | 
| 
      
 321 
     | 
    
         
            +
            	{
         
     | 
| 
      
 322 
     | 
    
         
            +
            	  expr_start_p = argv[i];
         
     | 
| 
      
 323 
     | 
    
         
            +
            	  expr_end_p = expr_end_p + strlen (expr_start_p);
         
     | 
| 
      
 324 
     | 
    
         
            +
            	  bp = expr_start_p;
         
     | 
| 
      
 325 
     | 
    
         
            +
            	  next;
         
     | 
| 
      
 326 
     | 
    
         
            +
            	  if (setjmp (top) == 0)
         
     | 
| 
      
 327 
     | 
    
         
            +
            	    {
         
     | 
| 
      
 328 
     | 
    
         
            +
            	      exp = expr ();
         
     | 
| 
      
 329 
     | 
    
         
            +
            	      if (round_flag)
         
     | 
| 
      
 330 
     | 
    
         
            +
            		exp = floor (exp + 0.5);
         
     | 
| 
      
 331 
     | 
    
         
            +
            	      output (exp);
         
     | 
| 
      
 332 
     | 
    
         
            +
            	    }
         
     | 
| 
      
 333 
     | 
    
         
            +
            	}
         
     | 
| 
      
 334 
     | 
    
         
            +
                }
         
     | 
| 
      
 335 
     | 
    
         
            +
              else
         
     | 
| 
      
 336 
     | 
    
         
            +
                {
         
     | 
| 
      
 337 
     | 
    
         
            +
            #define BUFSIZE 1024
         
     | 
| 
      
 338 
     | 
    
         
            +
                  char buf[BUFSIZE];
         
     | 
| 
      
 339 
     | 
    
         
            +
                  double exp;
         
     | 
| 
      
 340 
     | 
    
         
            +
             
     | 
| 
      
 341 
     | 
    
         
            +
                  for (;;)
         
     | 
| 
      
 342 
     | 
    
         
            +
            	{
         
     | 
| 
      
 343 
     | 
    
         
            +
            	  fputs ("eval> ", stdout);
         
     | 
| 
      
 344 
     | 
    
         
            +
            	  bp = fgets (buf, BUFSIZE, stdin);
         
     | 
| 
      
 345 
     | 
    
         
            +
            	  if (bp == NULL)
         
     | 
| 
      
 346 
     | 
    
         
            +
            	    break;
         
     | 
| 
      
 347 
     | 
    
         
            +
            	  next;
         
     | 
| 
      
 348 
     | 
    
         
            +
            	  if (setjmp (top) == 0)
         
     | 
| 
      
 349 
     | 
    
         
            +
            	    {
         
     | 
| 
      
 350 
     | 
    
         
            +
            	      exp = expr ();
         
     | 
| 
      
 351 
     | 
    
         
            +
            	      if (round_flag)
         
     | 
| 
      
 352 
     | 
    
         
            +
            		exp = floor (exp + 0.5);
         
     | 
| 
      
 353 
     | 
    
         
            +
            	      output (exp);
         
     | 
| 
      
 354 
     | 
    
         
            +
            	    }
         
     | 
| 
      
 355 
     | 
    
         
            +
            	}
         
     | 
| 
      
 356 
     | 
    
         
            +
                }
         
     | 
| 
      
 357 
     | 
    
         
            +
             
     | 
| 
      
 358 
     | 
    
         
            +
              exit (0);
         
     | 
| 
      
 359 
     | 
    
         
            +
            }
         
     |