\documentclass[pdftex,10pt]{article} \usepackage{amsmath,amsfonts,url} \usepackage[pdftex]{graphicx} \usepackage{booktabs} \usepackage{url} \setlength{\parindent}{0pt} \def\cour{\fontfamily{pcr}\selectfont} \usepackage[top=1in, bottom=0.8in, left=0.8in, right=0.8in]{geometry} \setcounter{tocdepth}{3} \newlength{\titrwidth} \setlength{\titrwidth}{\textwidth} \addtolength{\titrwidth}{-1.2in} \newlength{\methwidth} \setlength{\methwidth}{0.8in} \newlength{\defnwidth} \setlength{\defnwidth}{\textwidth} \addtolength{\defnwidth}{-1.2in} \addtolength{\heavyrulewidth}{\heavyrulewidth} \def\qquad{\quad\quad} \def\qqqquad{\quad\quad\quad\quad} \def\cc{\colon\colon} \def\gmpz{\textit{GMP::Z}} \def\gmpq{\textit{GMP::Q}} \def\gmpf{\textit{GMP::F}} \def\gmprandstate{\textit{GMP::RandState}} \def\gmpzs{\textit{GMP::Z}\ } \def\gmpqs{\textit{GMP::Q}\ } \def\gmpfs{\textit{GMP::F}\ } \def\gmprandstates{\textit{GMP::RandState\ }} \frenchspacing \begin{document} \begin{tabular}{p{1.0in} p{\titrwidth}} \huge{gmp} &\\ \midrule[3pt] \multicolumn{2}{r}{\large{Ruby bindings to the GMP library}}\\ \multicolumn{2}{r}{\large{Edition 0.5.3}}\\ \multicolumn{2}{r}{\large{20 September 2010}} \end{tabular} \vfill \large{written by Sam Rawlins}\\ \large{with extensive quoting from the GMP Manual} \newpage \vfill This manual describes how to use the gmp Ruby gem, which provides bindings to the GNU multiple precision arithmetic library, version 4.3.x or 5.0.x.\\ \\ Copyright 2009, 2010 Sam Rawlins.\\ No license yet. \newpage \tableofcontents \newpage \section{Introduction to GNU MP} This entire page is copied verbatim from the GMP Manual.\\\\ GNU MP is a portable library written in C for arbitrary precision arithmetic on integers, rational numbers, and floating-point numbers. It aims to provide the fastest possible arithmetic for all applications that need higher precision than is directly supported by the basic C types.\\ \\ Many applications use just a few hundred bits of precision; but some applications may need thousands or even millions of bits. GMP is designed to give good performance for both, by choosing algorithms based on the sizes of the operands, and by carefully keeping the overhead at a minimum.\\ \\ The speed of GMP is achieved by using fullwords as the basic arithmetic type, by using sophisticated algorithms, by including carefully optimized assembly code for the most common inner loops for many different CPUs, and by a general emphasis on speed (as opposed to simplicity or elegance).\\ \\ There is assembly code for these CPUs: ARM, DEC Alpha 21064, 21164, and 21264, AMD 29000, AMD K6, K6-2, Athlon, and Athlon64, Hitachi SuperH and SH-2, HPPA 1.0, 1.1, and 2.0, Intel Pentium, Pentium Pro/II/III, Pentium 4, generic x86, Intel IA-64, i960, Motorola MC68000, MC68020, MC88100, and MC88110, Motorola/IBM PowerPC 32 and 64, National NS32000, IBM POWER, MIPS R3000, R4000, SPARCv7, SuperSPARC, generic SPARCv8, UltraSPARC, DEC VAX, and Zilog Z8000. Some optimizations also for Cray vector systems, Clipper, IBM ROMP (RT), and Pyramid AP/XP.\\ \\ For up-to-date information on GMP, please see the GMP web pages at \url{http://gmplib.org/}\\ The latest version of the library is available at \url{ftp://ftp.gnu.org/gnu/gmp/}\\ Many sites around the world mirror '\url{ftp.gnu.org}', please use a mirror near you, see \url{http://www.gnu.org/order/ftp.html} for a full list.\\ \\ There are three public mailing lists of interest. One for release announcements, one for general questions and discussions about usage of the GMP library, and one for bug reports. For more information, see \url{http://gmplib.org/mailman/listinfo/}.\\ The proper place for bug reports is gmp-bugs@gmplib.org. See Chapter 4 [Reporting Bugs], page 28 for information about reporting bugs. \newpage \section{Introduction to MPFR} The gmp gem optionally interacts with the MPFR library as well. This entire page is copied verbatim from the MPFR manual.\\\\ The MPFR library is a C library for multiple-precision floating-point computations with correct rounding. MPFR has continuously been supported by the INRIA and the current main authors come from the Caramel and Arénaire project-teams at Loria (Nancy, France) and LIP (Lyon, France) respectively; see more on the credit page. MPFR is based on the GMP multiple-precision library.\\ The main goal of MPFR is to provide a library for multiple-precision floating-point computation which is both efficient and has a well-defined semantics. It copies the good ideas from the ANSI/IEEE-754 standard for double-precision floating-point arithmetic (53-bit mantissa).\\ MPFR is free. It is distributed under the GNU Lesser General Public License (GNU Lesser GPL), version 3 or later (2.1 or later for MPFR versions until 2.4.x). The library has been registered in France by the Agence de Protection des Programmes under the number IDDN FR 001 120020 00 R P 2000 000 10800, on 15 March 2000. This license guarantees your freedom to share and change MPFR, to make sure MPFR is free for all its users. Unlike the ordinary General Public License, the Lesser GPL enables developers of non-free programs to use MPFR in their programs. If you have written a new function for MPFR or improved an existing one, please share your work! \newpage \section{Introduction to the gmp gem} The gmp Ruby gem is a Ruby library that provides bindings to GMP. The gem is incomplete, and will likely only include a subset of the GMP functions. It is built as a C extension for Ruby, interacting with gmp.h. The gmp gem is not endorsed or supported by GNU or the GMP team (or MPFR team). The gmp gem also does not ship with GMP (or MPFR), so GMP (and MPFR) must be compiled separately. \section{Installing the gmp gem} \subsection{Prerequisites} OK. First, we've got a few requirements. To install the gmp gem, you need one of the following versions of Ruby: \begin{itemize} \item (MRI) Ruby 1.8.6 - tested lightly. \item (MRI) Ruby 1.8.7 - tested seriously. \item (MRI) Ruby 1.9.1 - tested seriously. \item (MRI) Ruby 1.9.2 - tested seriously. \end{itemize} As you can see only Matz's Ruby Interpreter (MRI) is supported. I haven't even put a thought into trying other interpreters/VMs. I intend to look into FFI, which supposedly will allow me to load this extension into JRuby and Rubinius, not sure about others...\\ Next is the platform, the combination of the architecture (processor) and OS. As far as I can tell, if you can compile GMP and Ruby (and optionally MPFR) on a given platform, you can use the gmp gem there too. Please report problems with that hypothesis.\\ Lastly, GMP (and MPFR). GMP (and MPFR) must be compiled and working. "And working" means you ran "make check" after compiling GMP (and MPFR), and it 'check's out. The following versions of GMP (and MPFR) have been tested: \begin{itemize} \item GMP 4.3.1 (with MPFR 2.4.2) \item GMP 4.3.2 (with MPFR 2.4.2 and 3.0.0) \item GMP 5.0.0 (with MPFR 3.0.0) \item GMP 5.0.1 (with MPFR 3.0.0) \end{itemize} That's all. I don't intend to test any older versions.\\ \newpage Here is a table of the exact environments on which I have tested the gmp gem. The (MPFR) version denotes that the gmp gem was tested both with and without the given version of MPFR:\\\\ \begin{tabular}{lrrr} \hline Platform & Ruby & GMP & (MPFR) \\ \midrule[1pt] Linux (Ubuntu NR 10.04) on x86 (32-bit) & (MRI) Ruby 1.8.7 & GMP 4.3.2 & (2.4.2) \\ & (MRI) Ruby 1.8.7 & GMP 5.0.1 & (3.0.0) \\ & (MRI) Ruby 1.9.1 & GMP 4.3.2 & (2.4.2) \\ & (MRI) Ruby 1.9.1 & GMP 5.0.1 & (3.0.0) \\ & (MRI) Ruby 1.9.2 & GMP 4.3.2 & (2.4.2) \\ & (MRI) Ruby 1.9.2 & GMP 5.0.1 & (3.0.0) \\ \hline Linux (Ubuntu 10.04) on x86\_64 (64-bit) & (MRI) Ruby 1.8.7 & GMP 4.3.2 & (2.4.2) \\ & (MRI) Ruby 1.8.7 & GMP 5.0.1 & (3.0.0) \\ & (MRI) Ruby 1.9.1 & GMP 4.3.2 & (2.4.2) \\ & (MRI) Ruby 1.9.1 & GMP 5.0.1 & (3.0.0) \\ & (MRI) Ruby 1.9.2 & GMP 4.3.2 & (2.4.2) \\ & (MRI) Ruby 1.9.2 & GMP 5.0.1 & (3.0.0) \\ \hline Mac OS X 10.6.4 on x86\_64 (64-bit) & (MRI) Ruby 1.8.7 & GMP 4.3.2 & (2.4.2) \\ & (MRI) Ruby 1.8.7 & GMP 5.0.1 & (3.0.0) \\ & (MRI) Ruby 1.9.1 & GMP 4.3.2 & (2.4.2) \\ & (MRI) Ruby 1.9.1 & GMP 5.0.1 & (3.0.0) \\ & (MRI) Ruby 1.9.2 & GMP 4.3.2 & (2.4.2) \\ & (MRI) Ruby 1.9.2 & GMP 5.0.1 & (3.0.0) \\ \hline Windows XP on x86 (32-bit) & (MRI) Ruby 1.9.1 & GMP 4.3.2 & (2.4.2) \\ & (MRI) Ruby 1.9.1 & GMP 5.0.1 & (3.0.0) \\ \hline \end{tabular}\\\\ In addition, I \textit{used to test} on the following environments, in versions 0.4.7 and earlier of the gmp gem:\\\\ \begin{tabular}{lrr} \hline Platform & Ruby & GMP \\ \midrule[1pt] Cygwin on x86 & (MRI) Ruby 1.8.7 & GMP 4.3.1 \\ \hline Linux (LinuxMint 7) on x86 & (MRI) Ruby 1.8.7 & GMP 4.3.1 \\ \hline Mac OS X 10.5.7 on x86 (32-bit) & (MRI) Ruby 1.8.6 & GMP 4.3.1 \\ \hline Mac OS X 10.5.7 on x86 (32-bit) & (MRI) Ruby 1.9.1 & GMP 4.3.1 \\ \hline \end{tabular} \subsection{Installing} You may clone the gmp gem's git repository with:\\ \\ \texttt{git clone git://github.com/srawlins/gmp.git}\\ Or you may install the gem from gemcutter (rubygems.org):\\ \\ \texttt{gem install gmp}\\ \newpage At this time, the gem self-compiles. If required libraries cannot be found, you may compile the C extensions manually with:\\ \\ \texttt{cd /ext}\\ \texttt{ruby extconf.rb}\\ \texttt{make}\\ There shouldn't be any errors, or warnings. \section{Testing the gmp gem} Testing the gmp gem is quite simple. The test/unit\_tests.rb suite uses Unit::Test. You can run this test suite with:\\ \\ \texttt{cd /test}\\ \texttt{ruby unit\_tests.rb}\\ All tests should pass. If you don't have the test-unit gem installed, then you may run into one error. It would look like:\\ \\ \texttt{ 1) Error:}\\ \texttt{test\_z\_div(TC\_division):}\\ \texttt{TypeError: GMP::Q can't be coerced into Float}\\ \texttt{ C:/Ruby191/devkit/msys/1.0.11/projects/gmp\_gem/test/tc\_division.rb:18:in `test\_z\_div'}\\ \section{GMP and gmp gem basics} \subsection{Classes} The gmp gem includes the namespace \texttt{GMP} and four classes within \texttt{GMP}: \begin{itemize} \item \texttt{GMP::Z} - Methods for signed integer arithmetic. There are about 64 methods here. \item \texttt{GMP::Q} - Methods for rational number arithmetic. There are at least 11 methods here (still accounting). \item \texttt{GMP::F} - Methods for floating-point arithmetic. There are at least 6 methods here (still accounting). \item \texttt{GMP::RandState} - Methods for random number generation. There are 3 methods here. \end{itemize} In addition to the above four classes, there are also four constants within \texttt{GMP}: \begin{itemize} \item \texttt{GMP::GMP\_VERSION} - The version of GMP linked into the gmp gem \item \texttt{GMP::GMP\_CC} - The compiler that compiled GMP linked into the gmp gem \item \texttt{GMP::GMP\_CFLAGS} - The compiler flags used to compile GMP linked into the gmp gem \item \texttt{GMP::GMP\_BITS\_PER\_LIMB} - The number of bits per limb \end{itemize} \section{MPFR basics} The gmp gem can optionally link to MPFR, the Multiple Precision Floating-Point Reliable Library. The x86-mswin32 version of the gmp gem comes with MPFR. This library uses the floating-point type from GMP, and thus the MPFR functions mapped in the gmp gem become methods in \texttt{GMP::F}. There are additional constants within \texttt{GMP} when MPFR is linked: \begin{itemize} \item \texttt{GMP::MPFR\_VERSION} - The version of MPFR linked into the gmp gem. \item \texttt{GMP::GMP\_RNDN} - Rounding mode representing "round to nearest." \item \texttt{GMP::GMP\_RNDZ} - Rounding mode representing "round toward zero." \item \texttt{GMP::GMP\_RNDU} - Rounding mode representing "round toward positive infinity." \item \texttt{GMP::GMP\_RNDD} - Rounding mode representing "round toward negative infinity." \item \texttt{GMP::MPFR\_RNDN} - Rounding mode representing "round to nearest."\\ (MPFR version 3.0.0 or higher only) \item \texttt{GMP::MPFR\_RNDZ} - Rounding mode representing "round toward zero."\\ (MPFR version 3.0.0 or higher only) \item \texttt{GMP::MPFR\_RNDU} - Rounding mode representing "round toward positive infinity."\\ (MPFR version 3.0.0 or higher only) \item \texttt{GMP::MPFR\_RNDD} - Rounding mode representing "round toward negative infinity."\\ (MPFR version 3.0.0 or higher only) \item \texttt{GMP::MPFR\_RNDZ} - Rounding mode representing "round away from zero."\\ (MPFR version 3.0.0 or higher only) \end{itemize} \newpage \section{Integer Functions} \subsection{Initializing, Assigning Integers} \begin{tabular}{p{\methwidth} l r} \toprule \textbf{new} & & GMP::Z.new $\rightarrow$ \textit{integer} \\ & & GMP::Z.new(\textit{numeric = 0}) $\rightarrow$ \textit{integer} \\ & & GMP::Z.new(\textit{str}) $\rightarrow$ \textit{integer} \\ \cmidrule(r){2-3} & \multicolumn{2}{p{\defnwidth}}{ This method creates a new \gmpzs integer. It takes one optional argument for the value of the integer. This argument can be one of several classes. Here are some examples:\newline \texttt{GMP::Z.new \qqqquad\qqqquad \#=> 0 (default) \newline GMP::Z.new(1) \qqqquad\qquad\ \#=> 1 (Ruby Fixnum) \newline GMP::Z.new("127") \qqqquad\ \#=> 127 (Ruby String)\newline GMP::Z.new(4294967296) \qquad \#=> 4294967296 (Ruby Bignum)\newline GMP::Z.new(GMP::Z.new(31)) \#=> 31 (GMP Integer)} } \end{tabular} \newline\newline There is also a convenience method available, \texttt{GMP::Z()}.\\ \subsection{Converting Integers} \begin{tabular}{p{\methwidth} l r} \toprule \textbf{to\_d} & & \textit{integer}.to\_d $\rightarrow$ \textit{float} \\ \cmidrule(r){2-3} & \multicolumn{2}{p{\defnwidth}}{ Returns \textit{integer} as an Float if \textit{integer} fits in a Float. Otherwise returns the least significant part of \texttt{integer}, with the same sign as \textit{integer}. If \textit{integer} is too big to fit in a Float, the returned result is probably not very useful. To find out if the value will fit, use the function \textit{mpz\_fits\_slong\_p} (\textbf{Unimplemented}). } \end{tabular} \newline\newline \begin{tabular}{p{\methwidth} l r} \toprule \textbf{to\_i} & & \textit{integer}.to\_i $\rightarrow$ \textit{fixnum} \\ \cmidrule(r){2-3} & \multicolumn{2}{p{\defnwidth}}{ Returns \textit{integer} as a Fixnum if \textit{integer} fits in a Fixnum. \newline Otherwise returns the least significant part of \textit{integer}, with the same sign as \textit{integer}. \newline If \textit{integer} is too big to fit in a \textit{Fixnum}, the returned result is probably not very useful. To find out if the value will fit, use the function \textit{mpz\_fits\_slong\_p} (\textbf{Unimplemented}). } \end{tabular} \newline\newline \begin{tabular}{p{\methwidth} l r} \toprule \textbf{to\_s} & & \textit{integer}.to\_s(\textit{base = 10}) $\rightarrow$ \textit{str} \\ \cmidrule(r){2-3} & \multicolumn{2}{p{\defnwidth}}{ Converts \textit{integer} to a string of digits in base \textit{base}. The \textit{base} argument may vary from 2 to 62 or from -2 to -36, or be a symbol, one of \textit{:bin}, \textit{:oct}, \textit{:dec}, or \textit{:hex}. \newline For \textit{base} in the range 2..36, digits and lower-case letters are used; for -2..-36 (and \textit{:bin}, \textit{:oct}, \textit{:dec}, and \textit{:hex}), digits and upper-case letters are used; for 37..62, digits, upper-case letters, and lower-case letters (in that significance order) are used. Here are some examples:\newline \texttt{GMP::Z(1).to\_s \qqqquad \#=> "1" \newline GMP::Z(32).to\_s(2) \qquad \#=> "100000" \newline GMP::Z(32).to\_s(4) \qquad \#=> "200" \newline GMP::Z(10).to\_s(16) \quad\ \#=> "a" \newline GMP::Z(10).to\_s(-16) \quad \#=> "A" \newline GMP::Z(255).to\_s(:bin) \#=> "11111111" \newline GMP::Z(255).to\_s(:oct) \#=> "377" \newline GMP::Z(255).to\_s(:dec) \#=> "255" \newline GMP::Z(255).to\_s(:hex) \#=> "ff"} } \end{tabular} \subsection{Integer Arithmetic} \begin{tabular}{p{\methwidth} l r} \toprule \textbf{+} & & \textit{integer} + \textit{numeric} $\rightarrow$ \textit{numeric} \\ \cmidrule(r){2-3} & \multicolumn{2}{p{\defnwidth}}{ Returns the sum of \textit{integer} and \textit{numeric}. \textit{numeric} can be an instance of \gmpz, \textit{Fixnum}, \gmpq, \gmpf, or \textit{Bignum}. } \end{tabular} \newline\newline \begin{tabular}{p{\methwidth} l r} \toprule \textbf{add!} & & \textit{integer}.add!(\textit{numeric}) $\rightarrow$ \textit{numeric} \\ \cmidrule(r){2-3} & \multicolumn{2}{p{\defnwidth}}{ Sums \textit{integer} and \textit{numeric}, in place. \textit{numeric} can be an instance of \gmpz, \textit{Fixnum}, \gmpq, \gmpf, or \textit{Bignum}. } \end{tabular} \newline\newline \begin{tabular}{p{\methwidth} l r} \toprule \textbf{-} & & \textit{integer} - \textit{numeric} $\rightarrow$ \textit{numeric} \\ & & \textit{integer}.sub!(\textit{numeric}) $\rightarrow$ \textit{numeric} \\ \cmidrule(r){2-3} & \multicolumn{2}{p{\defnwidth}}{ Returns the difference of \textit{integer} and \textit{numeric}. The destructive method calculates the difference in place. \textit{numeric} can be an instance of \gmpz, \textit{Fixnum}, \gmpq, \gmpf, or \textit{Bignum}. Here are some examples:\newline \texttt{seven = GMP::Z(7) \newline nine \ = GMP::Z(9) \newline half \ = GMP::Q(1,2) \newline pi \quad\ = GMP::F("3.14") \newline nine - 5 \qquad\quad \#=> 4 (GMP Integer) \newline nine - seven \quad \#=> 2 (GMP Integer) \newline nine - (2**32) \#=> -4294967287 (GMP Integer) \newline nine - nine \quad\ \#=> 0 (GMP Integer) \newline nine - half \quad\ \#=> 8.5 (GMP Rational) \newline nine - pi \qquad\ \#=> 5.86 (GMP Float)} } \end{tabular} \newline\newline \begin{tabular}{p{\methwidth} l r} \toprule \textbf{*} & & \textit{integer} * \textit{numeric} $\rightarrow$ \textit{numeric} \\ & & \textit{integer}.mul(\textit{numeric}) $\rightarrow$ \textit{numeric} \\ & & \textit{integer}.mul!(\textit{numeric}) $\rightarrow$ \textit{numeric} \\ \cmidrule(r){2-3} & \multicolumn{2}{p{\defnwidth}}{ Returns the product of \textit{integer} and \textit{numeric}. The destructive method calculates the product in place. \textit{numeric} can be an instance of \gmpz, \textit{Fixnum}, \gmpq, \gmpf, or \textit{Bignum}. } \end{tabular} \newline\newline \begin{tabular}{p{\methwidth} l r} \toprule \textbf{addmul!} & & \textit{integer}.addmul!(\textit{a}, \textit{b}) $\rightarrow$ \textit{numeric} \\ \cmidrule(r){2-3} & \multicolumn{2}{p{\defnwidth}}{ Sets \textit{integer} to the sum of \textit{integer} and the product of \textit{a} and \textit{b}. This destructive method calculates the result in place. Both \textit{a} and \textit{b} can be an instance of \gmpz, \textit{Fixnum}, or \textit{Bignum}. } \end{tabular} \newline\newline \begin{tabular}{p{\methwidth} l r} \toprule \textbf{\textless\textless} & & \textit{integer} \textless\textless \textit{numeric} $\rightarrow$ \textit{integer} \\ \cmidrule(r){2-3} & \multicolumn{2}{p{\defnwidth}}{ Returns \textit{integer} times 2 to the \textit{numeric} power. This can also be defined as a left shift by \textit{numeric} bits. } \end{tabular} \newline\newline \begin{tabular}{p{\methwidth} l r} \toprule \textbf{-@} & & -\textit{integer}\\ & & \textit{integer}.neg\\ & & \textit{integer}.neg!\\ \cmidrule(r){2-3} & \multicolumn{2}{p{\defnwidth}}{ Returns the negation, the additive inverse, of \textit{integer}. The destructive method negates in place. } \end{tabular} \newline\newline \begin{tabular}{p{\methwidth} l r} \toprule \textbf{abs} & & \textit{integer}.abs\\ & & \textit{integer}.abs!\\ \cmidrule(r){2-3} & \multicolumn{2}{p{\defnwidth}}{ Returns the absolute value of \textit{integer}. The destructive method calculates the absolute value in place. } \end{tabular} \subsection{Integer Division} \begin{tabular}{p{\methwidth} l r} \toprule \textbf{tdiv} & & $integer$.tdiv($numeric$) $\rightarrow$ $integer$\\ \cmidrule(r){2-3} & \multicolumn{2}{p{\defnwidth}}{ Returns the division of $integer$ by $numeric$, truncated. $numeric$ can be an instance of \gmpz, $Fixnum$, $Bignum$. The return object's class is always \gmpz. } \end{tabular} \newline\newline \begin{tabular}{p{\methwidth} l r} \toprule \textbf{fdiv} & & $integer$.fdiv($numeric$) $\rightarrow$ $integer$\\ \cmidrule(r){2-3} & \multicolumn{2}{p{\defnwidth}}{ Returns the division of $integer$ by $numeric$, floored. $numeric$ can be an instance of \gmpz, $Fixnum$, $Bignum$. The return object's class is always \gmpz. } \end{tabular} \newline\newline \begin{tabular}{p{\methwidth} l r} \toprule \textbf{cdiv} & & $integer$.cdiv($numeric$) $\rightarrow$ $integer$\\ \cmidrule(r){2-3} & \multicolumn{2}{p{\defnwidth}}{ Returns the ceiling division of $integer$ by $numeric$. $numeric$ can be an instance of \gmpz, $Fixnum$, $Bignum$. The return object's class is always \gmpz. } \end{tabular} \newline\newline \begin{tabular}{p{\methwidth} l r} \toprule \textbf{tmod} & & $integer$.tmod($numeric$) $\rightarrow$ $integer$\\ \cmidrule(r){2-3} & \multicolumn{2}{p{\defnwidth}}{ Returns the remainder after truncated division of $integer$ by $numeric$. $numeric$ can be an instance of \gmpz, $Fixnum$, or $Bignum$. The return object's class is always \gmpz. } \end{tabular} \newline\newline \begin{tabular}{p{\methwidth} l r} \toprule \textbf{fmod} & & $integer$.fmod($numeric$) $\rightarrow$ $integer$\\ \cmidrule(r){2-3} & \multicolumn{2}{p{\defnwidth}}{ Returns the remainder after floored division of $integer$ by $numeric$. $numeric$ can be an instance of \gmpz, $Fixnum$, or $Bignum$. The return object's class is always \gmpz. } \end{tabular} \newline\newline \begin{tabular}{p{\methwidth} l r} \toprule \textbf{cmod} & & \textit{integer}.cmod(\textit{numeric}) $\rightarrow$ \textit{integer}\\ \cmidrule(r){2-3} & \multicolumn{2}{p{\defnwidth}}{ Returns the remainder after ceilinged division of $integer$ by $numeric$. $numeric$ can be an instance of \gmpz, $Fixnum$, or $Bignum$. The return object's class is always \gmpz. } \end{tabular} \newline\newline \begin{tabular}{p{\methwidth} l r} \toprule \textbf{\%} & & \textit{integer} \% \textit{numeric} $\rightarrow$ \textit{integer}\\ \cmidrule(r){2-3} & \multicolumn{2}{p{\defnwidth}}{ Returns $integer$ modulo $numeric$. $numeric$ can be an instance of \gmpz, $Fixnum$, or $Bignum$. The return object's class is always \gmpz. } \end{tabular} \newpage \subsection{Integer Exponentiation} \begin{tabular}{p{\methwidth} l r} \toprule \textbf{**} & & \textit{integer} ** \textit{numeric} $\rightarrow$ \textit{numeric} \\ & & \textit{integer}.pow(\textit{numeric}) $\rightarrow$ \textit{numeric} \\ & & GMP::Z.pow(\textit{integer}, \textit{numeric}) $\rightarrow$ \textit{numeric} \\ \cmidrule(r){2-3} & \multicolumn{2}{p{\defnwidth}}{ Returns $integer$ raised to the $numeric$ power. In the singleton method (\textit{GMP::Z.pow()}), \textit{integer} can be either a \gmpz, $Fixnum$, $Bignum$, or $String$. } \end{tabular} \newline\newline \begin{tabular}{p{\methwidth} l r} \toprule \textbf{powmod} & & \textit{integer}.powmod(\textit{exp}, \textit{mod}) $\rightarrow$ \textit{integer} \\ \cmidrule(r){2-3} & \multicolumn{2}{p{\defnwidth}}{ Returns $integer$ raised to the $exp$ power, modulo $mod$. Negative $exp$ is supported if an inverse, $integer^{-1}$ modulo $mod$, exists. If an inverse doesn't exist then a divide by zero exception is raised. } \end{tabular} \subsection{Integer Roots} \begin{tabular}{p{\methwidth} l r} \toprule \textbf{root} & & \textit{integer}.root(\textit{numeric}) $\rightarrow$ \textit{numeric} \\ \cmidrule(r){2-3} & \multicolumn{2}{p{\defnwidth}}{ Returns the integer part of the $numeric$'th root of $integer$. } \end{tabular} \newline\newline \begin{tabular}{p{\methwidth} l r} \toprule \textbf{sqrt} & & \textit{integer}.sqrt $\rightarrow$ \textit{numeric} \\ & & \textit{integer}.sqrt! $\rightarrow$ \textit{numeric} \\ \cmidrule(r){2-3} & \multicolumn{2}{p{\defnwidth}}{ Returns the truncated integer part of the square root of $integer$. } \end{tabular} \newline\newline \begin{tabular}{p{\methwidth} l r} \toprule \textbf{sqrtrem} & & \textit{integer}.sqrtrem $\rightarrow$ \textit{sqrt}, \textit{rem} \\ \cmidrule(r){2-3} & \multicolumn{2}{p{\defnwidth}}{ Returns the truncated integer part of the square root of $integer$ as $sqrt$ and the remainder, $integer - sqrt * sqrt$, as $rem$, which will be zero if $integer$ is a perfect square. } \end{tabular} \newline\newline \begin{tabular}{p{\methwidth} l r} \toprule \textbf{power?} & & \textit{integer}.power? $\rightarrow$ \textit{true} \textbar\ \textit{false} \\ \cmidrule(r){2-3} & \multicolumn{2}{p{\defnwidth}}{ Returns true if $integer$ is a perfect power, i.e., if there exist integers $a$ and $b$, with $b > 1$, such that $integer$ equals $a$ raised to the power $b$. \newline\newline Under this definition both 0 and 1 are considered to be perfect powers. Negative values of integers are accepted, but of course can only be odd perfect powers. } \end{tabular} \newline\newline \begin{tabular}{p{\methwidth} l r} \toprule \textbf{square?} & & \textit{integer}.square? $\rightarrow$ \textit{true} \textbar\ \textit{false} \\ \cmidrule(r){2-3} & \multicolumn{2}{p{\defnwidth}}{ Returns true if $integer$ is a perfect square, i.e., if the square root of $integer$ is an integer. Under this definition both 0 and 1 are considered to be perfect squares. } \end{tabular} \subsection{Number Theoretic Functions} \begin{tabular}{p{\methwidth} l r} \toprule \textbf{is\_probab\_prime?} & & $integer$.is\_probab\_prime?($reps = 5$) $\rightarrow$ 0, 1, or 2 \\ \cmidrule(r){2-3} & \multicolumn{2}{p{\defnwidth}}{ Determine whether $integer$ is prime. Returns 2 if $integer$ is definitely prime, returns 1 if $integer$ is probably prime (without being certain), or returns 0 if $integer$ is definitely composite. \newline\newline This function does some trial divisions, then some Miller-Rabin probabilistic primality tests. $reps$ controls how many such tests are done, 5 to 10 is a reasonable number, more will reduce the chances of a composite being returned as “probably prime”. \newline\newline Miller-Rabin and similar tests can be more properly called compositeness tests. Numbers which fail are known to be composite but those which pass might be prime or might be composite. Only a few composites pass, hence those which pass are considered probably prime. } \end{tabular} \newline\newline \begin{tabular}{p{\methwidth} l r} \toprule \textbf{next\_prime} & & $integer$.next\_prime $\rightarrow$ $prime$ \\ & & $integer$.nextprime $\rightarrow$ $prime$ \\ & & $integer$.next\_prime! $\rightarrow$ $prime$ \\ & & $integer$.nextprime! $\rightarrow$ $prime$ \\ \cmidrule(r){2-3} & \multicolumn{2}{p{\defnwidth}}{ Returns the next prime greater than $integer$. The destructive method sets $integer$ to the next prime greater than $integer$. \newline\newline This function uses a probabilistic algorithm to identify primes. For practical purposes it's adequate, the chance of a composite passing will be extremely small. } \end{tabular} \newline\newline \begin{tabular}{p{\methwidth} l r} \toprule \textbf{gcd} & & $a$.gcd($b$) $\rightarrow$ $g$ \\ \cmidrule(r){2-3} & \multicolumn{2}{p{\defnwidth}}{ Computes the greatest common divisor of $a$ and $b$. $g$ will always be positive, even if $a$ or $b$ is negative. $b$ can be an instance of \gmpz, $Fixnum$, or $Bignum$. \newline\newline \texttt{GMP::Z(24).gcd(GMP::Z(8)) \quad \#=> GMP::Z(8) \newline GMP::Z(24).gcd(8) \quad \#=> GMP::Z(8) \newline GMP::Z(24).gcd(2**32) \quad \#=> GMP::Z(8)} } \end{tabular} \newline\newline \begin{tabular}{p{\methwidth} l r} \toprule \textbf{invert} & & $a$.invert($m$) $\rightarrow$ $integer$ \\ \cmidrule(r){2-3} & \multicolumn{2}{p{\defnwidth}}{ Computes the inverse of $a$ mod $m$. $m$ can be an instance of \gmpz, $Fixnum$, or $Bignum$. \newline\newline \texttt{GMP::Z(2).invert(GMP::Z(11)) \quad \#=> GMP::Z(6) \newline GMP::Z(3).invert(11) \quad \#=> GMP::Z(4) \newline GMP::Z(5).invert(11) \quad \#=> GMP::Z(9)} } \end{tabular} \newline\newline \begin{tabular}{p{\methwidth} l r} \toprule \textbf{jacobi} & & $a$.jacobi($b$) $\rightarrow$ $integer$ \\ & & GMP::Z.jacobi($a$, $b$) $\rightarrow$ $integer$ \\ \cmidrule(r){2-3} & \multicolumn{2}{p{\defnwidth}}{ Returns the Jacobi symbol $(a/b)$. This is defined only for $b$ odd. If $b$ is even, a range exception will be raised. \newline\newline \textit{GMP::Z.jacobi} (the instance method) requires $b$ to be an instance of \gmpz. \newline \textit{GMP::Z\#jacobi} (the class method) requires $a$ and $b$ each to be an instance of \gmpz, $Fixnum$, or $Bignum$. } \end{tabular} \newline\newline \begin{tabular}{p{\methwidth} l r} \toprule \textbf{legendre} & & $a$.legendre($b$) $\rightarrow$ $integer$ \\ \cmidrule(r){2-3} & \multicolumn{2}{p{\defnwidth}}{ Returns the Legendre symbol $(a/b)$. This is defined only for $p$ an odd positive prime. If $p$ is even, negative, or composite, a range exception will be raised. } \end{tabular} \newline\newline \begin{tabular}{p{\methwidth} l r} \toprule \textbf{remove} & & $n$.remove($factor$) $\rightarrow$ ($integer$, $times$) \\ \cmidrule(r){2-3} & \multicolumn{2}{p{\defnwidth}}{ Remove all occurrences of the factor $factor$ from $n$. $factor$ can be an instance of \gmpz, $Fixnum$, or $Bignum$. $integer$ is the resulting integer, an instance of \gmpz. $times$ is how many times $factor$ was removed, a $Fixnum$. } \end{tabular} \newline\newline \begin{tabular}{p{\methwidth} l r} \toprule \textbf{fac} & & GMP::Z.fac($n$) $\rightarrow$ $integer$ \\ \cmidrule(r){2-3} & \multicolumn{2}{p{\defnwidth}}{ Returns $n!$, or, $n$ factorial. } \end{tabular} \newline\newline \begin{tabular}{p{\methwidth} l r} \toprule \textbf{fib} & & GMP::Z.fib($n$) $\rightarrow$ $integer$ \\ \cmidrule(r){2-3} & \multicolumn{2}{p{\defnwidth}}{ Returns $F[n]$, or, the $n$th Fibonacci number. } \end{tabular} \subsection{Integer Comparisons} \begin{tabular}{p{\methwidth} l r} \toprule \textbf{\textless=\textgreater} & & $a$ \textless=\textgreater\ $b$ $\rightarrow$ $fixnum$ \\ \cmidrule(r){2-3} & \multicolumn{2}{p{\defnwidth}}{ Returns a negative Fixnum if $a$ is less than $b$.\newline Returns 0 if $a$ is equal to $b$.\newline Returns a positive Fixnum if $a$ is greater than $b$. } \end{tabular} \newline\newline \begin{tabular}{p{\methwidth} l r} \toprule \textbf{\textless} & & $a$ \textless\ $b$ $\rightarrow$ $boolean$ \\ \cmidrule(r){2-3} & \multicolumn{2}{p{\defnwidth}}{ Returns true if $a$ is less than $b$. } \end{tabular} \newline\newline \begin{tabular}{p{\methwidth} l r} \toprule \textbf{\textless=} & & $a$ \textless=\ $b$ $\rightarrow$ $boolean$ \\ \cmidrule(r){2-3} & \multicolumn{2}{p{\defnwidth}}{ Returns true if $a$ is less than or equal to $b$. } \end{tabular} \newline\newline \begin{tabular}{p{\methwidth} l r} \toprule \textbf{==} & & $a$ == $b$ $\rightarrow$ $boolean$ \\ \cmidrule(r){2-3} & \multicolumn{2}{p{\defnwidth}}{ Returns true if $a$ is equal to $b$. } \end{tabular} \newline\newline \begin{tabular}{p{\methwidth} l r} \toprule \textbf{\textgreater=} & & $a$ \textgreater= $b$ $\rightarrow$ $boolean$ \\ \cmidrule(r){2-3} & \multicolumn{2}{p{\defnwidth}}{ Returns true if $a$ is greater than or equal to $b$. } \end{tabular} \newline\newline \begin{tabular}{p{\methwidth} l r} \toprule \textbf{\textgreater} & & $a$ \textgreater\ $b$ $\rightarrow$ $boolean$ \\ \cmidrule(r){2-3} & \multicolumn{2}{p{\defnwidth}}{ Returns true if $a$ is greater than $b$. } \end{tabular} \newline\newline \begin{tabular}{p{\methwidth} l r} \toprule \textbf{cmpabs} & & $a$.cmpabs($b$) $\rightarrow$ $fixnum$ \\ \cmidrule(r){2-3} & \multicolumn{2}{p{\defnwidth}}{ Returns a negative Fixnum if abs($a$) is less than abs($b$).\newline Returns 0 if abs($a$) is equal to abs($b$).\newline Returns a positive Fixnum if abs($a$) is greater than abs($b$). } \end{tabular} \newline\newline \begin{tabular}{p{\methwidth} l r} \toprule \textbf{sgn} & & $a$.sgn $\rightarrow$ $-1$, $0$, or $1$ \\ \cmidrule(r){2-3} & \multicolumn{2}{p{\defnwidth}}{ Returns -1 if $a$ is less than $b$.\newline Returns 0 if $a$ is equal to $b$.\newline Returns 1 if $a$ is greater than $b$. } \end{tabular} \newline\newline \begin{tabular}{p{\methwidth} l r} \toprule \textbf{eql?} & & $a$.eql?($b$) $\rightarrow$ $boolean$ \\ \cmidrule(r){2-3} & \multicolumn{2}{p{\defnwidth}}{ Used when comparing objects as Hash keys. } \end{tabular} \newline\newline \begin{tabular}{p{\methwidth} l r} \toprule \textbf{hash} & & $a$.hash $\rightarrow$ $string$ \\ \cmidrule(r){2-3} & \multicolumn{2}{p{\defnwidth}}{ Used when comparing objects as $Hash$ keys. } \end{tabular} \subsection{Integer Logic and Bit Fiddling} \begin{tabular}{p{\methwidth} l r} \toprule \textbf{and} & & $a$ \& $b$ $\rightarrow$ $integer$ \\ \cmidrule(r){2-3} & \multicolumn{2}{p{\defnwidth}}{ Returns $integer$, the bitwise and of $a$ and $b$. } \end{tabular} \newline\newline \begin{tabular}{p{\methwidth} l r} \toprule \textbf{ior} & & $a$ \textbar\ $b$ $\rightarrow$ $integer$ \\ \cmidrule(r){2-3} & \multicolumn{2}{p{\defnwidth}}{ Returns $integer$, the bitwise inclusive or of $a$ and $b$. } \end{tabular} \newline\newline \begin{tabular}{p{\methwidth} l r} \toprule \textbf{xor} & & $a$ \textasciicircum\ $b$ $\rightarrow$ $integer$ \\ \cmidrule(r){2-3} & \multicolumn{2}{p{\defnwidth}}{ Returns $integer$, the bitwise exclusive or of $a$ and $b$. } \end{tabular} \newline\newline \begin{tabular}{p{\methwidth} l r} \toprule \textbf{com} & & $integer$.com $\rightarrow$ $complement$ \\ & & $integer$.com! $\rightarrow$ $complement$ \\ \cmidrule(r){2-3} & \multicolumn{2}{p{\defnwidth}}{ Returns the one's complement of $integer$. The destructive method sets $integer$ to the one's complement of $integer$. } \end{tabular} \newline\newline \begin{tabular}{p{\methwidth} l r} \toprule \textbf{popcount} & & $n$.popcount $\rightarrow$ $fixnum$ \\ \cmidrule(r){2-3} & \multicolumn{2}{p{\defnwidth}}{ If $n>=0$, return the population count of $n$, which is the number of 1 bits in the binary representation. If $n<0$, the number of 1s is infinite, and the return value is the largest possible $mp\_bitcnt\_t$. } \end{tabular} \newline\newline \begin{tabular}{p{\methwidth} l r} \toprule \textbf{scan0} & & $n$.scan0($i$) $\rightarrow$ $integer$ \\ \cmidrule(r){2-3} & \multicolumn{2}{p{\defnwidth}}{ Scans $n$, starting from bit $i$, towards more significant bits, until the first 0 bit is found. Return the index of the found bit. \newline\newline If the bit at $i$ is already what's sought, then $i$ is returned. \newline\newline If there's no bit found, then $INT2FIX(ULONG\_MAX)$ is returned. This will happen in scan0 past the end of a negative number. } \end{tabular} \newline\newline \begin{tabular}{p{\methwidth} l r} \toprule \textbf{scan1} & & $n$.scan1($i$) $\rightarrow$ $integer$ \\ \cmidrule(r){2-3} & \multicolumn{2}{p{\defnwidth}}{ Scans $n$, starting from bit $i$, towards more significant bits, until the first 1 bit is found. Return the index of the found bit. \newline\newline If the bit at $i$ is already what's sought, then $i$ is returned. \newline\newline If there's no bit found, then $INT2FIX(ULONG\_MAX)$ is returned. This will happen in scan1 past the end of a negative number. } \end{tabular} \newline\newline \begin{tabular}{p{\methwidth} l r} \toprule \textbf{[]} & & $n$[$bit\_index$] $\rightarrow$ $0$ or $1$ \\ \cmidrule(r){2-3} & \multicolumn{2}{p{\defnwidth}}{ Tests bit $bit\_index$ in $n$ and return $0$ or $1$ accordingly. } \end{tabular} \newline\newline \begin{tabular}{p{\methwidth} l r} \toprule \textbf{[]=} & & $n$[$bit\_index$]=$i$ $\rightarrow$ $nil$ \\ \cmidrule(r){2-3} & \multicolumn{2}{p{\defnwidth}}{ Sets bit $bit\_index$ in $n$ to $i$. } \end{tabular} \newpage \subsection{Miscellaneous Integer Functions} \begin{tabular}{p{\methwidth} l r} \toprule \textbf{odd?} & & $n$.odd? $\rightarrow$ $boolean$ \\ \cmidrule(r){2-3} & \multicolumn{2}{p{\defnwidth}}{ Returns whether $n$ is odd. } \end{tabular} \newline\newline \begin{tabular}{p{\methwidth} l r} \toprule \textbf{even?} & & $n$.even? $\rightarrow$ $boolean$ \\ \cmidrule(r){2-3} & \multicolumn{2}{p{\defnwidth}}{ Returns whether $n$ is even. } \end{tabular} \newline\newline \begin{tabular}{p{\methwidth} l r} \toprule \textbf{sizeinbase} & & $n$.sizeinbase($b$) $\rightarrow$ $digits$ \\ \cmidrule(r){2-3} & \multicolumn{2}{p{\defnwidth}}{ Returns the number of digits in base $b$. $b$ can vary between 2 and 62. } \end{tabular} \newline\newline \begin{tabular}{p{\methwidth} l r} \toprule \textbf{size\_in\_bin} & & $n$.size\_in\_bin $\rightarrow$ $digits$ \\ \cmidrule(r){2-3} & \multicolumn{2}{p{\defnwidth}}{ Returns the number of digits in $n$'s binary representation. } \end{tabular} \subsection{Integer Special Functions} \begin{tabular}{p{\methwidth} l r} \toprule \textbf{size} & & $integer$.size $\rightarrow$ $fixnum$ \\ \cmidrule(r){2-3} & \multicolumn{2}{p{\defnwidth}}{ Returns the size of \textit{integer} measured in number of limbs. If \textit{integer} is zero, then the returned value will be zero. } \end{tabular} \newpage \section{Rational Functions} \subsection{Initializing, Assigning Rationals} \begin{tabular}{p{\methwidth} l r} \toprule \textbf{new} & & GMP::Q.new $\rightarrow$ \textit{rational} \\ & & GMP::Q.new(\textit{numerator = 0}, \textit{denominator = 1}) $\rightarrow$ \textit{rational} \\ & & GMP::Q.new(\textit{str}) $\rightarrow$ \textit{rational} \\ \cmidrule(r){2-3} & \multicolumn{2}{p{\defnwidth}}{ This method creates a new \gmpq rational number. It takes two optional arguments for the value of the numerator and denominator. These arguments can each be an instance of several classes. Here are some examples:\newline \texttt{GMP::Q.new \qqqquad\qqqquad \#=> 0 (default) \newline GMP::Q.new(1) \qqqquad\qquad\ \#=> 1 (Ruby Fixnum) \newline GMP::Q.new(1,3) \qqqquad\quad\ \#=> 1/3 (Ruby Fixnums) \newline GMP::Q.new("127") \qqqquad\ \#=> 127 (Ruby String)\newline GMP::Q.new(4294967296) \qquad \#=> 4294967296 (Ruby Bignum)\newline GMP::Q.new(GMP::Z.new(31)) \#=> 31 (GMP Integer)} } \end{tabular} \newline\newline There is also a convenience method available, \texttt{GMP::Q()}.\\ \subsection{Converting Rationals} \begin{tabular}{p{\methwidth} l r} \toprule \textbf{to\_d} & & \textit{rational}.to\_d $\rightarrow$ \textit{float} \\ \cmidrule(r){2-3} & \multicolumn{2}{p{\defnwidth}}{ Returns \textit{rational} as an Float if \textit{rational} fits in a Float. Otherwise returns the least significant part of \texttt{rational}, with the same sign as \textit{rational}. If \textit{rational} is too big to fit in a Float, the returned result is probably not very useful. } \end{tabular} \newline\newline \begin{tabular}{p{\methwidth} l r} \toprule \textbf{to\_s} & & \textit{rational}.to\_s $\rightarrow$ \textit{str} \\ \cmidrule(r){2-3} & \multicolumn{2}{p{\defnwidth}}{ Converts \textit{rational} to a string. } \end{tabular} \newpage \section{Floating-point Functions} \subsection{Initializing, Assigning Floats} \subsection{Floating-point Special Functions (MPFR Only)} Every method below accepts two additional parameters in addition to any required parameters. These are $rnd_mode$, the rounding mode to use in calculation, which defaults to \textit{GMP::GMP\_RNDN}, and $res_prec$, the precision of the result, which defaults to the \textit{f.prec}, the precision of $f$.\\ \begin{tabular}{p{\methwidth} l r} \toprule \textbf{log} & & $f$.log(\begin{small}rnd\_mode = GMP\_RNDN, res\_prec=$f$.prec\end{small}) $\rightarrow$ $g$ \\ \textbf{log2} & & $f$.log2(\begin{small}rnd\_mode = GMP\_RNDN, res\_prec=$f$.prec\end{small}) $\rightarrow$ $g$ \\ \textbf{log10} & & $f$.log10(\begin{small}rnd\_mode = GMP\_RNDN, res\_prec=$f$.prec\end{small}) $\rightarrow$ $g$ \\ \cmidrule(r){2-3} & \multicolumn{2}{p{\defnwidth}}{ Returns the natural log, $\log_2$, and $\log_10$ of $f$, respectively. Returns $-Inf$ if $f$ is $-0$. } \end{tabular} \newline\newline \begin{tabular}{p{\methwidth} l r} \toprule \textbf{exp} & & $f$.exp(\begin{small}rnd\_mode = GMP\_RNDN, res\_prec=$f$.prec\end{small}) $\rightarrow$ $g$ \\ \textbf{exp2} & & $f$.exp2(\begin{small}rnd\_mode = GMP\_RNDN, res\_prec=$f$.prec\end{small}) $\rightarrow$ $g$ \\ \textbf{exp10} & & $f$.exp10(\begin{small}rnd\_mode = GMP\_RNDN, res\_prec=$f$.prec\end{small}) $\rightarrow$ $g$ \\ \cmidrule(r){2-3} & \multicolumn{2}{p{\defnwidth}}{ Returns the exponential of $f$, $2$ to the power of $f$, and $10$ to the power of $f$, respectively. } \end{tabular} \newline\newline \begin{tabular}{p{\methwidth} l r} \toprule \textbf{cos} & & $f$.cos(\begin{small}rnd\_mode = GMP\_RNDN, res\_prec=$f$.prec\end{small}) $\rightarrow$ $g$ \\ \textbf{sin} & & $f$.sin(\begin{small}rnd\_mode = GMP\_RNDN, res\_prec=$f$.prec\end{small}) $\rightarrow$ $g$ \\ \textbf{tan} & & $f$.tan(\begin{small}rnd\_mode = GMP\_RNDN, res\_prec=$f$.prec\end{small}) $\rightarrow$ $g$ \\ \cmidrule(r){2-3} & \multicolumn{2}{p{\defnwidth}}{ Returns the cosine, sine, and tangent of $f$, respectively. } \end{tabular} \newline\newline \begin{tabular}{p{\methwidth} l r} \toprule \textbf{sec} & & $f$.sec(\begin{small}rnd\_mode = GMP\_RNDN, res\_prec=$f$.prec\end{small}) $\rightarrow$ $g$ \\ \textbf{csc} & & $f$.csc(\begin{small}rnd\_mode = GMP\_RNDN, res\_prec=$f$.prec\end{small}) $\rightarrow$ $g$ \\ \textbf{cot} & & $f$.cot(\begin{small}rnd\_mode = GMP\_RNDN, res\_prec=$f$.prec\end{small}) $\rightarrow$ $g$ \\ \cmidrule(r){2-3} & \multicolumn{2}{p{\defnwidth}}{ Returns the secant, cosecant, and cotangent of $f$, respectively. } \end{tabular} \newline\newline \begin{tabular}{p{\methwidth} l r} \toprule \textbf{acos} & & $f$.acos(\begin{small}rnd\_mode = GMP\_RNDN, res\_prec=$f$.prec\end{small}) $\rightarrow$ $g$ \\ \textbf{asin} & & $f$.asin(\begin{small}rnd\_mode = GMP\_RNDN, res\_prec=$f$.prec\end{small}) $\rightarrow$ $g$ \\ \textbf{atan} & & $f$.atan(\begin{small}rnd\_mode = GMP\_RNDN, res\_prec=$f$.prec\end{small}) $\rightarrow$ $g$ \\ \cmidrule(r){2-3} & \multicolumn{2}{p{\defnwidth}}{ Returns the arc-cosine, arc-sine, and arc-tangent of $f$, respectively. } \end{tabular} \newline\newline \begin{tabular}{p{\methwidth} l r} \toprule \textbf{cosh} & & $f$.cosh(\begin{small}rnd\_mode = GMP\_RNDN, res\_prec=$f$.prec\end{small}) $\rightarrow$ $g$ \\ \textbf{sinh} & & $f$.sinh(\begin{small}rnd\_mode = GMP\_RNDN, res\_prec=$f$.prec\end{small}) $\rightarrow$ $g$ \\ \textbf{tanh} & & $f$.tanh(\begin{small}rnd\_mode = GMP\_RNDN, res\_prec=$f$.prec\end{small}) $\rightarrow$ $g$ \\ \cmidrule(r){2-3} & \multicolumn{2}{p{\defnwidth}}{ Returns the hyperbolic cosine, sine, and tangent of $f$, respectively. } \end{tabular} \newline\newline \begin{tabular}{p{\methwidth} l r} \toprule \textbf{sech} & & $f$.sech(\begin{small}rnd\_mode = GMP\_RNDN, res\_prec=$f$.prec\end{small}) $\rightarrow$ $g$ \\ \textbf{csch} & & $f$.csch(\begin{small}rnd\_mode = GMP\_RNDN, res\_prec=$f$.prec\end{small}) $\rightarrow$ $g$ \\ \textbf{coth} & & $f$.coth(\begin{small}rnd\_mode = GMP\_RNDN, res\_prec=$f$.prec\end{small}) $\rightarrow$ $g$ \\ \cmidrule(r){2-3} & \multicolumn{2}{p{\defnwidth}}{ Returns the hyperbolic secant, cosecant, and cotangent of $f$, respectively. } \end{tabular} \newline\newline \begin{tabular}{p{\methwidth} l r} \toprule \textbf{acosh} & & $f$.acosh(\begin{small}rnd\_mode = GMP\_RNDN, res\_prec=$f$.prec\end{small}) $\rightarrow$ $g$ \\ \textbf{asinh} & & $f$.asinh(\begin{small}rnd\_mode = GMP\_RNDN, res\_prec=$f$.prec\end{small}) $\rightarrow$ $g$ \\ \textbf{atanh} & & $f$.atanh(\begin{small}rnd\_mode = GMP\_RNDN, res\_prec=$f$.prec\end{small}) $\rightarrow$ $g$ \\ \cmidrule(r){2-3} & \multicolumn{2}{p{\defnwidth}}{ Returns the hyperbolic arc-cosine, arc-sine, and arc-tangent of $f$, respectively. } \end{tabular} \newline\newline \begin{tabular}{p{\methwidth} l r} \toprule \textbf{log1p} & & $f$.log1p(\begin{small}rnd\_mode = GMP\_RNDN, res\_prec=$f$.prec\end{small}) $\rightarrow$ $g$ \\ \cmidrule(r){2-3} & \multicolumn{2}{p{\defnwidth}}{ Returns the logarithm of 1 plus $f$. } \end{tabular} \newline\newline \begin{tabular}{p{\methwidth} l r} \toprule \textbf{expm1} & & $f$.expm1(\begin{small}rnd\_mode = GMP\_RNDN, res\_prec=$f$.prec\end{small}) $\rightarrow$ $g$ \\ \cmidrule(r){2-3} & \multicolumn{2}{p{\defnwidth}}{ Returns the exponential of $f$ minus 1. } \end{tabular} \newline\newline \begin{tabular}{p{\methwidth} l r} \toprule \textbf{eint} & & $f$.eint(\begin{small}rnd\_mode = GMP\_RNDN, res\_prec=$f$.prec\end{small}) $\rightarrow$ $g$ \\ \cmidrule(r){2-3} & \multicolumn{2}{p{\defnwidth}}{ Returns the exponential integral of $f$. For positive $f$, the exponential integral is the sum of Euler's constant, of the logarithm of $f$, and of the sum for $k$ from $1$ to infinity of $f$ to the power $k$, divided by $k$ and factorial($k$). For negative $f$, this method returns NaN. } \end{tabular} \newline\newline \begin{tabular}{p{\methwidth} l r} \toprule \textbf{li2} & & $f$.li2(\begin{small}rnd\_mode = GMP\_RNDN, res\_prec=$f$.prec\end{small}) $\rightarrow$ $g$ \\ \cmidrule(r){2-3} & \multicolumn{2}{p{\defnwidth}}{ Returns the real part of the dilogarithm of $f$. MPFR defines the dilogarithm as the integral of $-\log(1-t)/t$ from 0 to $f$. } \end{tabular} \newline\newline \begin{tabular}{p{\methwidth} l r} \toprule \textbf{gamma} & & $f$.gamma(\begin{small}rnd\_mode = GMP\_RNDN, res\_prec=$f$.prec\end{small}) $\rightarrow$ $g$ \\ \cmidrule(r){2-3} & \multicolumn{2}{p{\defnwidth}}{ Returns the value of the Gamma function on $f$. When $f$ is a negative integer, this method returns NaN. } \end{tabular} \newline\newline \begin{tabular}{p{\methwidth} l r} \toprule \textbf{lngamma} & & $f$.lngamma(\begin{small}rnd\_mode = GMP\_RNDN, res\_prec=$f$.prec\end{small}) $\rightarrow$ $g$ \\ \cmidrule(r){2-3} & \multicolumn{2}{p{\defnwidth}}{ Returns the value of the logarithm of the Gamma function on $f$. When $-2k-1 \leq f \leq -2k$, $k$ being a non-negative integer, this method returns NaN. } \end{tabular} \newline\newline \begin{tabular}{p{\methwidth} l r} \toprule \textbf{digamma} & & $f$.digamma(\begin{small}rnd\_mode = GMP\_RNDN, res\_prec=$f$.prec\end{small}) $\rightarrow$ $g$ \\ \cmidrule(r){2-3} & \multicolumn{2}{p{\defnwidth}}{ Returns the value of the Digamma (sometimes called Psi) function on $f$. When $f$ is negative, this method returns NaN.\newline \newline Only available in MPFR version 3.0.0 or later. } \end{tabular} \newline\newline \begin{tabular}{p{\methwidth} l r} \toprule \textbf{zeta} & & $f$.zeta(\begin{small}rnd\_mode = GMP\_RNDN, res\_prec=$f$.prec\end{small}) $\rightarrow$ $g$ \\ \cmidrule(r){2-3} & \multicolumn{2}{p{\defnwidth}}{ Returns the value of the Riemann Zeta function on $f$. } \end{tabular} \newline\newline \begin{tabular}{p{\methwidth} l r} \toprule \textbf{erf} & & $f$.erf(\begin{small}rnd\_mode = GMP\_RNDN, res\_prec=$f$.prec\end{small}) $\rightarrow$ $g$ \\ \textbf{erfc} & & $f$.erfc(\begin{small}rnd\_mode = GMP\_RNDN, res\_prec=$f$.prec\end{small}) $\rightarrow$ $g$ \\ \cmidrule(r){2-3} & \multicolumn{2}{p{\defnwidth}}{ Returns the value of the error function on $f$ (respectively the complementary error function on $f$). } \end{tabular} \newline\newline \begin{tabular}{p{\methwidth} l r} \toprule \textbf{j0} & & $f$.j0(\begin{small}rnd\_mode = GMP\_RNDN, res\_prec=$f$.prec\end{small}) $\rightarrow$ $g$ \\ \textbf{j1} & & $f$.j1(\begin{small}rnd\_mode = GMP\_RNDN, res\_prec=$f$.prec\end{small}) $\rightarrow$ $g$ \\ \textbf{jn} & & $f$.jn(\begin{small}rnd\_mode = GMP\_RNDN, res\_prec=$f$.prec\end{small}) $\rightarrow$ $g$ \\ \cmidrule(r){2-3} & \multicolumn{2}{p{\defnwidth}}{ Returns the value of the first kind Bessel function of order $0$ (respectively $1$ and $n$) on $f$. When $f$ is NaN, this method returns NaN. When $f$ is +Inf or -Inf, this method returns $+0$. When $f$ is zero, this method returns +Inf or -Inf, depending on the parity and sign of $n$, and the sign of $f$. } \end{tabular} \newline\newline \begin{tabular}{p{\methwidth} l r} \toprule \textbf{y0} & & $f$.y0(\begin{small}rnd\_mode = GMP\_RNDN, res\_prec=$f$.prec\end{small}) $\rightarrow$ $g$ \\ \textbf{y1} & & $f$.y1(\begin{small}rnd\_mode = GMP\_RNDN, res\_prec=$f$.prec\end{small}) $\rightarrow$ $g$ \\ \textbf{yn} & & $f$.yn(\begin{small}rnd\_mode = GMP\_RNDN, res\_prec=$f$.prec\end{small}) $\rightarrow$ $g$ \\ \cmidrule(r){2-3} & \multicolumn{2}{p{\defnwidth}}{ Returns the value of the second kind Bessel function of order $0$ (respectively $1$ and $n$) on $f$. When $f$ is NaN or negative, this method returns NaN. When $f$ is +Inf, this method returns $+0$. When $f$ is zero, this method returns +Inf or -Inf, depending on the parity and sign of $n$. } \end{tabular} \newpage \section{Random Number Functions} \subsection{Random State Initialization} \begin{tabular}{p{\methwidth} l r} \toprule \textbf{new} & & GMP::RandState.new $\rightarrow$ \textit{mersenne twister state} \\ & & GMP::RandState.new(:default) $\rightarrow$ \textit{mersenne twister state} \\ & & GMP::RandState(:mt) $\rightarrow$ \textit{mersenne twister random state} \\ & & GMP::RandState.new(:lc\_2exp, a, c, m2exp) $\rightarrow$ \textit{linear congruential state} \\ & & GMP::RandState.new(:lc\_2exp\_size, size) $\rightarrow$ \textit{linear congruential state} \\ \cmidrule(r){2-3} & \multicolumn{2}{p{\defnwidth}}{ This method creates a new \gmprandstate instance. The first argument defaults to \textit{:default} (also \textit{:mt}), which initializes the \gmprandstate for a Mersenne Twister algorithm. No other arguments should be given if \textit{:default} or \textit{:mt} is specified. \newline\newline If the first argument given is \textit{:lc\_2exp}, then the \gmprandstate is initialized for a linear congruential algorithm. \textit{:lc\_2exp} must be followed with $a$, $c$, and $m2exp$. The algorithm can then proceed as ($X = (a*X + c) \mod 2^{m2exp}$). \newline\newline \gmprandstate can also be initialized for a linear congruential algorithm with \textit{:lc\_2exp\_size}. This initializer instead takes just one argument, $size$. $a$, $c$, and $m2exp$ are then chosen from a table, with $m2exp/2 > size$. The maximum size currently supported is 128.\newline \texttt{GMP::RandState.new \newline GMP::RandState.new(:mt) \newline GMP::RandState.new(:lc\_2exp, 1103515245, 12345, 15) \quad \#=> Perl's old rand() \newline GMP::RandState.new(:lc\_2exp, 25\_214\_903\_917, 11, 48) \quad \#=> drand48} } \end{tabular} \subsection{Random State Seeding} \begin{tabular}{p{\methwidth} l r} \toprule \textbf{seed} & & $state$.seed($integer$) $\rightarrow$ $integer$ \\ \cmidrule(r){2-3} & \multicolumn{2}{p{\defnwidth}}{ Set an initial seed value into $state$. $integer$ can be an instance of \gmpz, $Fixnum$, or $Bignum$. } \end{tabular} \subsection{Integer Random Numbers} \begin{tabular}{p{\methwidth} l r} \toprule \textbf{urandomb} & & $state$.urandomb($n$) $\rightarrow$ $integer$ \\ \cmidrule(r){2-3} & \multicolumn{2}{p{\defnwidth}}{ Generates a uniformly distributed random integer in the range $0$ to $2^n -1$, inclusive. } \end{tabular} \newline\newline \begin{tabular}{p{\methwidth} l r} \toprule \textbf{urandomm} & & $state$.urandomm($n$) $\rightarrow$ $integer$ \\ \cmidrule(r){2-3} & \multicolumn{2}{p{\defnwidth}}{ Generates a uniformly distributed random integer in the range $0$ to $n -1$, inclusive. $n$ can be an instance of \gmpz, $Fixnum$, or $Bignum$. } \end{tabular} \newpage \section{Benchmarking} Starting with, I believe, GMP 5.0.0, their benchmarking suite was updated to version 0.2, a significant improvement over version 0.1. The suite consists of 3 parts.\\\\ First is six individual programs that will benchmark a single concept. These are \texttt{multiply}, \texttt{divide}, \texttt{gcd}, \texttt{gcdext}, \texttt{rsa}, and \texttt{pi}. Second is gexpr.c, a nifty little program (compiled with \texttt{gcc -o gexpr gexpr.c}, or\\ \texttt{gcc -o gexpr gexpr.c -lm} on some systems). They use this basically for weighing the results of individual tests and stringifying them to a certain precision. Third is runbench, a shell script that runs each of the six benchmark programs, each several times with a different set of arguments. It compiles the results, using gexpr to carefully calculate a final "score" for each benchmark, each benchmark family (\texttt{rsa} and \texttt{pi} are separated as "app" benchmarks.), and for the suite as a whole. \subsection{gmp gem benchmarking} The structure described above lends itself perfectly to some simple modifications that allow me to benchmark the gmp gem. Instead of using the C programs that are the individual benchmarks, I have converted them into Ruby programs, and called them the same names. When runbench executes "multiply" for example, it is running a Ruby program that does the same general thing as "multiply" the C program. This allows me to benchmark the gmp gem, and I can even compare the results with those of benchmarking GMP itself. I have done so below. \newpage \subsection{Benchmark Results} I've benchmarked an array of Ruby-version/GMP-version combinations, which can be compared with results of the actual GMPbench benchmark, in order to understand the overhead that Ruby and the Ruby C Extension API impose on the GMP library. The benchmarks listed were all executed on an Apple MacBook "5.1." booting three operating systems with rEFIt 0.14. Because not all of the marks from GMPbench have been ported to the Ruby gmp gem, results for 'base' and 'app' are not listed; they cannot be compared with GMPbench results.\\ \begin{LARGE}MacBook, Intel Core 2 Duo, 2 GHz, 2 GB DDR3\end{LARGE}\\ Mac OS X 10.6.4, x86 (32-bit)\\ Ruby and GMP compiled with gcc 4.2.1 (Apple Inc. build 5664)\\ \begin{tabular}{|l|l|r|r|r|r|} \hline GMP & bench & Ruby 1.8.7 & Ruby 1.9.1 & Ruby 1.9.2 & C \\ \hline 4.3.2 & multiply & 7696.5 & 7482.8 & 7608.2 & 16789 \\ & divide & 7304.3 & 7148.0 & 7199.4 & 9872.5 \\ & gcd & 2388.4 & 2412.1 & 2470.9 & 2938.9 \\ & rsa & 2042.3 & 2058.0 & 2065.9 & 2136.7 \\ \hline 5.0.1 & multiply & 8142.6 & 7886.0 & 7952.7 & 17925 \\ & divide & 10256 & 10088 & 10124 & 16069 \\ & gcd & 2498.1 & 2547.0 & 2574.2 & 3063.7 \\ & rsa & 2132.4 & 2157.4 & 2167.9 & 2229.2 \\ \hline \end{tabular}\\\\ Ubuntu 10.04, Kernel 2.6.32-24, x86\_64 (64-bit)\\ Ruby and GMP compiled with gcc 4.4.3 (Ubuntu 4.4.3-4ubuntu5)\\ \begin{tabular}{|l|l|r|r|r|r|} \hline GMP & bench & Ruby 1.8.7 & Ruby 1.9.1 & Ruby 1.9.2 & C \\ \hline 4.3.2 & multiply & 7793.7 & 6825.7 & 7460.6 & 14716 \\ & divide & 7687.6 & 7725.9 & 7473.3 & 8614.3 \\ & gcd & 2450.1 & 2507.6 & 2476.6 & 2779.8 \\ & rsa & 1979.1 & 2065.6 & 2059.2 & 1984.3 \\ \hline 5.0.1 & multiply & 9727.1 & 7020.3 & 7902.1 & 17695 \\ & divide & 9306.4 & 10785 & 10799 & 15629 \\ & gcd & 2345.3 & 2525.5 & 2541.2 & 2925.1 \\ & rsa & 2116.5 & 2117.8 & 2143.9 & 2233.4 \\ \hline \end{tabular}\\\\ Windows 7 (64-bit)\\ Ruby and GMP compiled with gcc 4.5.0 (tdm-1)\\ \begin{tabular}{|l|l|r|r|r|r|} \hline GMP & bench & Ruby 1.8.7 & Ruby 1.9.1 & Ruby 1.9.2 & C \\ \hline 4.3.2 & multiply & 3514.7 & 3649.4 & 3631.9 & 6448.7 \\ & divide & 2996.7 & 3082.0 & 3065.2 & 3717.5 \\ & gcd & 1142.8 & 1183.3 & 1203.6 & 1359.4 \\ & rsa & 719.41 & 730.05 & 736.03 & 757.97 \\ \hline 5.0.1 & multiply & 3702.9 & 3824.1 & 3763.8 & 6835.2 \\ & divide & 4549.7 & 4600.9 & 4609.2 & 6497.4 \\ & gcd & 1204.9 & 1233.4 & 1235.0 & 1394.2 \\ & rsa & 729.68 & 735.13 & 728.56 & 754.72 \\ \hline \end{tabular}\\ \end{document}