├── LICENSE ├── TODO ├── WARNING ├── changes.txt ├── demos └── ex1.c ├── float.ilg ├── float.ind ├── float.pdf ├── float.tex ├── makefile ├── mpf_abs.c ├── mpf_acos.c ├── mpf_add.c ├── mpf_add_d.c ├── mpf_asin.c ├── mpf_atan.c ├── mpf_clear.c ├── mpf_clear_multi.c ├── mpf_cmp.c ├── mpf_cmp_d.c ├── mpf_const_0.c ├── mpf_const_1pi.c ├── mpf_const_1r2.c ├── mpf_const_2pi.c ├── mpf_const_2rpi.c ├── mpf_const_d.c ├── mpf_const_e.c ├── mpf_const_l10e.c ├── mpf_const_l2e.c ├── mpf_const_le2.c ├── mpf_const_ln_d.c ├── mpf_const_pi.c ├── mpf_const_pi2.c ├── mpf_const_pi4.c ├── mpf_const_r2.c ├── mpf_const_sqrt_d.c ├── mpf_copy.c ├── mpf_cos.c ├── mpf_div.c ├── mpf_div_2.c ├── mpf_div_d.c ├── mpf_exch.c ├── mpf_exp.c ├── mpf_init.c ├── mpf_init_copy.c ├── mpf_init_multi.c ├── mpf_inv.c ├── mpf_invsqrt.c ├── mpf_iterations.c ├── mpf_ln.c ├── mpf_mul.c ├── mpf_mul_2.c ├── mpf_mul_d.c ├── mpf_neg.c ├── mpf_normalize.c ├── mpf_normalize_to.c ├── mpf_pow.c ├── mpf_sin.c ├── mpf_sqr.c ├── mpf_sqrt.c ├── mpf_sub.c ├── mpf_sub_d.c ├── mpf_tan.c └── tomfloat.h /LICENSE: -------------------------------------------------------------------------------- 1 | LibTomFloat is licensed under DUAL licensing terms. 2 | 3 | Choose and use the license of your needs. 4 | 5 | [LICENSE #1] 6 | 7 | LibTomFloat is public domain. As should all quality software be. 8 | 9 | Tom St Denis 10 | 11 | [/LICENSE #1] 12 | 13 | [LICENSE #2] 14 | 15 | DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE 16 | Version 2, December 2004 17 | 18 | Copyright (C) 2004 Sam Hocevar 19 | 20 | Everyone is permitted to copy and distribute verbatim or modified 21 | copies of this license document, and changing it is allowed as long 22 | as the name is changed. 23 | 24 | DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE 25 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 26 | 27 | 0. You just DO WHAT THE FUCK YOU WANT TO. 28 | 29 | [/LICENSE #2] 30 | -------------------------------------------------------------------------------- /TODO: -------------------------------------------------------------------------------- 1 | Still quite a bit todo for LibTomFloat. 2 | 3 | 1. The following functions [as of v0.01] have not been implemented (the .C files are present but not populated) 4 | 5 | - mpf_acos 6 | - mpf_asin 7 | - mpf_atan 8 | - mpf_const_1pi [*] 9 | - mpf_const_2pi [*] 10 | - mpf_const_2rpi [*] 11 | - mpf_const_l10e [*] 12 | - mpf_const_l2e [*] 13 | - mpf_const_le2 [*] 14 | - mpf_const_pi [*] 15 | - mpf_const_pi2 [*] 16 | - mpf_const_pi4 [*] 17 | - mpf_ln 18 | - mpf_pow [*] 19 | - Any form of string input/output 20 | 21 | [*] Denotes functions which are written but depend upon incomplete functions to work. 22 | 23 | The critical path lies in two functions. The first is mpf_ln from which I can write mpf_pow and the various constants will function. 24 | The second is mpf_atan from which I can write mpf_const_pi and finish off the missing constants. 25 | 26 | From there it's a matter of adding mpf_asin, mpf_acos and mpf_tan and I have a decent subset of math in there. 27 | 28 | 2. Once all of the functions have been written I want to add early-out optimizations to the various series calculations. Right now 29 | they use an arbitrary high count and get accurate results. However, quite a few functions stabalize quickly and do not need so many 30 | iterations. In particular I plan to start on mpf_invsqrt() as it forms the basis of mpf_inv() which is used in mpf_cos() [and other trigs]. 31 | 32 | At the same time I want to add more domain checking (e.g. valid inputs). 33 | 34 | 3. Add decent string input/output 35 | 36 | 4. More things to the manual. I plan on doing this with every release cycle though. 37 | 38 | 5. MSVC makefile 39 | -------------------------------------------------------------------------------- /WARNING: -------------------------------------------------------------------------------- 1 | LibTomFloat is a *VERY* new package and is not even fully written yet. Quite a 2 | bit of the functionality is present but will be changing in the near future to allow 3 | for optimizations (e.g. early-outs). 4 | 5 | Please don't use LibTomFloat just yet for any production or fielded system. 6 | 7 | By all means if you wish to test and help find bugs in LibTomFloat give the package a try. 8 | 9 | I do not guarantee the numerical accuracy of this package as of yet. 10 | 11 | You've been warned. 12 | -------------------------------------------------------------------------------- /changes.txt: -------------------------------------------------------------------------------- 1 | June 21st, 2004 2 | v0.02 -- Added missing objects to the makefile [oops] 3 | -- fixed up mpf_add and mpf_sub to be more reliable about the precision 4 | -- added required limited ln function mpf_ln_l (domain 0 < x <= 2) 5 | It's still incomplete as it converges slowly (and therefore yields incorrect results) 6 | -- Added mpf_ln and mpf_atan 7 | -- Added short-circuits to sin, cos, invsqrt, atan, ln and sqrt [huge speedup] 8 | -- Optimized mpf_sqrt and mpf_invsqrt by using quick estimates. Fixed 9 | circular dependency as well (mpf_sqrt requires mpf_invsqrt but not vice versa) 10 | ++ Note: No further releases are planned for a while. I encourage interested 11 | parties to fork this code base and extend it! 12 | 13 | May 5th, 2004 14 | v0.01 -- wrote base of LTF 15 | 16 | Anytime 17 | v0.00 -- no LTF existed. 18 | -------------------------------------------------------------------------------- /demos/ex1.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void draw(mp_float *a) 4 | { 5 | char buf[8192]; 6 | mp_toradix(&(a->mantissa), buf, 10); 7 | printf("%s * 2^%ld\n", buf, a->exp); 8 | } 9 | 10 | int main(void) 11 | { 12 | mp_float a, b, c, d, e; 13 | int err; 14 | 15 | mpf_init_multi(100, &a, &b, &c, &d, &e, NULL); 16 | 17 | mpf_const_d(&a, 1); draw(&a); 18 | mpf_const_d(&b, 2); draw(&b); 19 | mpf_const_d(&c, 3); draw(&c); 20 | mpf_const_d(&d, 4); draw(&d); 21 | 22 | mpf_add(&b, &c, &e); printf("2 + 3 == "); draw(&e); 23 | mpf_sub(&b, &c, &e); printf("2 - 3 =="); draw(&e); 24 | mpf_mul(&b, &c, &e); printf("2 * 3 == "); draw(&e); 25 | mpf_div(&b, &c, &e); printf("2 / 3 == "); draw(&e); 26 | mpf_add_d(&b, 3, &e); printf("2 + 3 == "); draw(&e); 27 | mpf_sub_d(&b, 3, &e); printf("2 - 3 =="); draw(&e); 28 | mpf_mul_d(&b, 3, &e); printf("2 * 3 == "); draw(&e); 29 | mpf_div_d (&b, 3, &e); printf("2 / 3 == "); draw(&e); 30 | mpf_const_d(&e, 0); mpf_add_d(&e, 1, &e); printf("0 + 1 == "); draw(&e); 31 | mpf_const_d(&e, 0); mpf_sub_d(&e, 1, &e); printf("0 - 1 == "); draw(&e); 32 | printf("\n"); 33 | mpf_invsqrt(&d, &e); printf("1/sqrt(4) == 1/2 == "); draw(&e); 34 | mpf_invsqrt(&c, &e); printf("1/sqrt(3) == "); draw(&e); 35 | mpf_inv(&a, &e); printf("1/1 == "); draw(&e); 36 | mpf_inv(&b, &e); printf("1/2 == "); draw(&e); 37 | mpf_inv(&c, &e); printf("1/3 == "); draw(&e); 38 | mpf_inv(&d, &e); printf("1/4 == "); draw(&e); 39 | printf("\n"); 40 | mpf_const_pi(&e); printf("Pi == "); draw(&e); 41 | printf("\n"); 42 | mpf_const_e(&e); printf("e == "); draw(&e); 43 | mpf_exp(&c, &e); printf("e^3 == "); draw(&e); 44 | mpf_sqrt(&e, &e); printf("sqrt(e^3) == "); draw(&e); 45 | mpf_sqr(&e, &e); printf("sqrt(e^3)^2 == "); draw(&e); 46 | printf("\n"); 47 | mpf_cos(&a, &e); printf("cos(1) == "); draw(&e); 48 | mpf_cos(&b, &e); printf("cos(2) == "); draw(&e); 49 | mpf_cos(&c, &e); printf("cos(3) == "); draw(&e); 50 | mpf_cos(&d, &e); printf("cos(4) == "); draw(&e); 51 | mpf_sin(&a, &e); printf("sin(1) == "); draw(&e); 52 | mpf_sin(&b, &e); printf("sin(2) == "); draw(&e); 53 | mpf_sin(&c, &e); printf("sin(3) == "); draw(&e); 54 | mpf_sin(&d, &e); printf("sin(4) == "); draw(&e); 55 | mpf_tan(&a, &e); printf("tan(1) == "); draw(&e); 56 | mpf_tan(&b, &e); printf("tan(2) == "); draw(&e); 57 | mpf_tan(&c, &e); printf("tan(3) == "); draw(&e); 58 | mpf_tan(&d, &e); printf("tan(4) == "); draw(&e); 59 | mpf_inv(&a, &e); mpf_atan(&e, &e); printf("atan(1/1) == "); draw(&e); 60 | mpf_inv(&b, &e); mpf_atan(&e, &e); printf("atan(1/2) == "); draw(&e); 61 | mpf_inv(&c, &e); mpf_atan(&e, &e); printf("atan(1/3) == "); draw(&e); 62 | mpf_inv(&d, &e); mpf_atan(&e, &e); printf("atan(1/4) == "); draw(&e); 63 | printf("\n"); 64 | #define lntest(x) if ((err = mpf_const_ln_d(&e, x)) != MP_OKAY) { printf("Failed ln(%3d), %d\n", x, err); } else { printf("ln(%3d) == ", x); draw(&e); }; 65 | lntest(0); 66 | lntest(1); 67 | lntest(2); 68 | lntest(4); 69 | lntest(8); 70 | lntest(17); 71 | lntest(1000); 72 | lntest(100000); 73 | lntest(250000); 74 | return 0; 75 | } 76 | 77 | 78 | 79 | -------------------------------------------------------------------------------- /float.ilg: -------------------------------------------------------------------------------- 1 | This is makeindex, version 2.14 [02-Oct-2002] (kpathsea + Thai support). 2 | Scanning input file float.idx....done (48 entries accepted, 0 rejected). 3 | Sorting entries....done (285 comparisons). 4 | Generating output file float.ind....done (55 lines written, 0 warnings). 5 | Output written in float.ind. 6 | Transcript written in float.ilg. 7 | -------------------------------------------------------------------------------- /float.ind: -------------------------------------------------------------------------------- 1 | \begin{theindex} 2 | 3 | \item exponent, \hyperpage{2} 4 | 5 | \indexspace 6 | 7 | \item mantissa, \hyperpage{2} 8 | \item mp\_cmp, \hyperpage{16} 9 | \item mp\_error\_to\_string, \hyperpage{6} 10 | \item MP\_MEM, \hyperpage{5} 11 | \item MP\_NO, \hyperpage{5} 12 | \item MP\_OKAY, \hyperpage{5} 13 | \item MP\_VAL, \hyperpage{5} 14 | \item MP\_YES, \hyperpage{5} 15 | \item mpf\_abs, \hyperpage{13} 16 | \item mpf\_acos, \hyperpage{18} 17 | \item mpf\_add, \hyperpage{15} 18 | \item mpf\_add\_d, \hyperpage{15} 19 | \item mpf\_asin, \hyperpage{18} 20 | \item mpf\_atan, \hyperpage{18} 21 | \item mpf\_clear, \hyperpage{7} 22 | \item mpf\_clear\_multi, \hyperpage{8} 23 | \item mpf\_cmp\_d, \hyperpage{16} 24 | \item mpf\_const\_0, \hyperpage{11} 25 | \item mpf\_const\_d, \hyperpage{11} 26 | \item mpf\_const\_ln\_d, \hyperpage{11} 27 | \item mpf\_const\_sqrt\_d, \hyperpage{11} 28 | \item mpf\_copy, \hyperpage{9} 29 | \item mpf\_cos, \hyperpage{18} 30 | \item mpf\_div, \hyperpage{15} 31 | \item mpf\_div\_2, \hyperpage{16} 32 | \item mpf\_div\_d, \hyperpage{15} 33 | \item mpf\_exch, \hyperpage{10} 34 | \item mpf\_exp, \hyperpage{17} 35 | \item mpf\_init, \hyperpage{7} 36 | \item mpf\_init\_copy, \hyperpage{8} 37 | \item mpf\_init\_multi, \hyperpage{8} 38 | \item mpf\_inv, \hyperpage{18} 39 | \item mpf\_invsqrt, \hyperpage{18} 40 | \item mpf\_ln, \hyperpage{17} 41 | \item mpf\_mul, \hyperpage{15} 42 | \item mpf\_mul\_2, \hyperpage{16} 43 | \item mpf\_mul\_d, \hyperpage{15} 44 | \item mpf\_neg, \hyperpage{13} 45 | \item mpf\_normalize, \hyperpage{11} 46 | \item mpf\_normalize\_to, \hyperpage{11} 47 | \item mpf\_pow, \hyperpage{17} 48 | \item mpf\_sin, \hyperpage{18} 49 | \item mpf\_sqr, \hyperpage{16} 50 | \item mpf\_sqrt, \hyperpage{18} 51 | \item mpf\_sub, \hyperpage{15} 52 | \item mpf\_sub\_d, \hyperpage{15} 53 | \item mpf\_tan, \hyperpage{18} 54 | 55 | \end{theindex} 56 | -------------------------------------------------------------------------------- /float.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/libtom/libtomfloat/e7812b59bbe10030f27e721c295535278dd09335/float.pdf -------------------------------------------------------------------------------- /float.tex: -------------------------------------------------------------------------------- 1 | \documentclass[b5paper]{book} 2 | \usepackage{hyperref} 3 | \usepackage{makeidx} 4 | \usepackage{amssymb} 5 | \usepackage{color} 6 | \usepackage{alltt} 7 | \usepackage{graphicx} 8 | \usepackage{layout} 9 | \def\union{\cup} 10 | \def\intersect{\cap} 11 | \def\getsrandom{\stackrel{\rm R}{\gets}} 12 | \def\cross{\times} 13 | \def\cat{\hspace{0.5em} \| \hspace{0.5em}} 14 | \def\catn{$\|$} 15 | \def\divides{\hspace{0.3em} | \hspace{0.3em}} 16 | \def\nequiv{\not\equiv} 17 | \def\approx{\raisebox{0.2ex}{\mbox{\small $\sim$}}} 18 | \def\lcm{{\rm lcm}} 19 | \def\gcd{{\rm gcd}} 20 | \def\log{{\rm log}} 21 | \def\ord{{\rm ord}} 22 | \def\abs{{\mathit abs}} 23 | \def\rep{{\mathit rep}} 24 | \def\mod{{\mathit\ mod\ }} 25 | \renewcommand{\pmod}[1]{\ ({\rm mod\ }{#1})} 26 | \newcommand{\floor}[1]{\left\lfloor{#1}\right\rfloor} 27 | \newcommand{\ceil}[1]{\left\lceil{#1}\right\rceil} 28 | \def\Or{{\rm\ or\ }} 29 | \def\And{{\rm\ and\ }} 30 | \def\iff{\hspace{1em}\Longleftrightarrow\hspace{1em}} 31 | \def\implies{\Rightarrow} 32 | \def\undefined{{\rm ``undefined"}} 33 | \def\Proof{\vspace{1ex}\noindent {\bf Proof:}\hspace{1em}} 34 | \let\oldphi\phi 35 | \def\phi{\varphi} 36 | \def\Pr{{\rm Pr}} 37 | \newcommand{\str}[1]{{\mathbf{#1}}} 38 | \def\F{{\mathbb F}} 39 | \def\N{{\mathbb N}} 40 | \def\Z{{\mathbb Z}} 41 | \def\R{{\mathbb R}} 42 | \def\C{{\mathbb C}} 43 | \def\Q{{\mathbb Q}} 44 | \definecolor{DGray}{gray}{0.5} 45 | \newcommand{\emailaddr}[1]{\mbox{$<${#1}$>$}} 46 | \def\twiddle{\raisebox{0.3ex}{\mbox{\tiny $\sim$}}} 47 | \def\gap{\vspace{0.5ex}} 48 | \makeindex 49 | \begin{document} 50 | \frontmatter 51 | \pagestyle{empty} 52 | \title{LibTomFloat User Manual \\ v0.02} 53 | \author{Tom St Denis \\ tomstdenis@iahu.ca} 54 | \maketitle 55 | This text and the library are hereby placed in the public domain. This book has been formatted for B5 [176x250] paper using the \LaTeX{} {\em book} 56 | macro package. 57 | 58 | \vspace{10cm} 59 | 60 | \begin{flushright}Open Source. Open Academia. Open Minds. 61 | 62 | \mbox{ } 63 | 64 | Tom St Denis, 65 | 66 | Ontario, Canada 67 | \end{flushright} 68 | 69 | \tableofcontents 70 | \listoffigures 71 | \mainmatter 72 | \pagestyle{headings} 73 | \chapter{Introduction} 74 | \section{What is LibTomFloat?} 75 | LibTomFloat is a library of source code that provides multiple precision floating point arithmetic. It allows developers to manipulate floating 76 | point numbers of variable precision. The library was written in portable ISO C source code and depends upon the public domain 77 | LibTomMath package. 78 | 79 | Along with providing the core mathematical operations such as addition and subtraction LibTomFloat also provides various complicated algorithms 80 | such as trigonometry's sine, cosine and tangent operators as well as Calculus's square root, inverse square root, exponential and logarithm 81 | operators. 82 | 83 | LibTomFloat has been written for portability and numerical stability and is not particularly optimized for any given platform. It uses optimal 84 | algorithms for manipulating the mantissa by using LibTomMath and uses numerically stable series for the various trig and calculus functions. 85 | 86 | \section{License} 87 | LibTomFloat is public domain. 88 | 89 | \section{Building LibTomFloat} 90 | LibTomFloat requires version 0.30 or higher of LibTomMath to be installed in order to build. Once LibTomMath is installed building LibTomFloat 91 | is as simple as: 92 | 93 | \begin{alltt} 94 | make 95 | \end{alltt} 96 | 97 | Which will build ``libtomfloat.a'' and along with ``tomfloat.h'' complete an installation of LibTomFloat. You can also use the make target 98 | ``install'' to automatically build and copy the files (into *NIX specific) locations. 99 | 100 | \begin{alltt} 101 | make install 102 | \end{alltt} 103 | 104 | \textbf{Note}: LibTomFloat does not use ISO C's native floating point types which means that the standard math library does not have to be 105 | linked in. This also means that LibTomFloat will work decently on platforms that do not have a floating point unit. 106 | 107 | 108 | \section{Purpose of LibTomFloat} 109 | LibTomFloat is as much as an exercise in hardcore math for myself as it is a service to any programmer who needs high precision float point 110 | data types. ISO C provides for fairly reasonable precision floating point data types but is limited. A proper analogy is LibTomFloat solves 111 | ISO C's floating point problems in the same way LibTomMath solves ISO C's integer data type problems. 112 | 113 | A classic example of a good use for large precision floats is long simulations where the numbers are not perfectly stable. A $128$--bit mantissa 114 | (for example) can provide for exceptional precision. 115 | 116 | That and knowing the value of $e$ to 512 bits is fun. 117 | 118 | \section{How the types work} 119 | 120 | \index{mantissa} \index{exponent} 121 | The floating point types are emulated with three components. The \textbf{mantissa}, the \textbf{exponent} and the \textbf{radix}. 122 | The mantissa forms the digits of number being represented. The exponent scales the number to give it a larger range. The radix controls 123 | how many bits there are in the mantissa. The larger the radix the more precise the types become. 124 | 125 | The representation of a number is given by the simple product $m \cdot 2^e$ where $m$ is the mantissa and $e$ the exponent. Numbers are 126 | always normalized such that there are $radix$ bits per mantissa. For example, with $radix = 16$ the number $2$ is represented by 127 | $32768 \cdot 2^{-14}$. A zero is represented by a mantissa of zero and an exponent of one and is a special case. 128 | 129 | The sign flag is a standard ISO C ``long'' which gives it the range $2^{-31} \le e < 2^{31}$ which is considerably large. 130 | 131 | Technically, LibTomFloat does not implement IEEE standard floating point types. The exponent is not normalized and the sign flag does not 132 | count as a bit in the radix. There is also no ``implied'' bit in this system. The mantissa explicitly dictates the digits. 133 | 134 | \chapter{Getting Started with LibTomFloat} 135 | \section{Building Programs} 136 | In order to use libTomFloat you must include ``tomfloat.h'' and link against the appropriate library file (typically 137 | libtomfloat.a). There is no library initialization required and the entire library is thread safe. 138 | 139 | \section{Return Codes} 140 | There are three possible return codes a function may return. 141 | 142 | \index{MP\_OKAY}\index{MP\_YES}\index{MP\_NO}\index{MP\_VAL}\index{MP\_MEM} 143 | \begin{figure}[here!] 144 | \begin{center} 145 | \begin{small} 146 | \begin{tabular}{|l|l|} 147 | \hline \textbf{Code} & \textbf{Meaning} \\ 148 | \hline MP\_OKAY & The function succeeded. \\ 149 | \hline MP\_VAL & The function input was invalid. \\ 150 | \hline MP\_MEM & Heap memory exhausted. \\ 151 | \hline &\\ 152 | \hline MP\_YES & Response is yes. \\ 153 | \hline MP\_NO & Response is no. \\ 154 | \hline 155 | \end{tabular} 156 | \end{small} 157 | \end{center} 158 | \caption{Return Codes} 159 | \end{figure} 160 | 161 | The last two codes listed are not actually ``return'ed'' by a function. They are placed in an integer (the caller must 162 | provide the address of an integer it can store to) which the caller can access. To convert one of the three return codes 163 | to a string use the following function. 164 | 165 | \index{mp\_error\_to\_string} 166 | \begin{alltt} 167 | char *mp_error_to_string(int code); 168 | \end{alltt} 169 | 170 | This will return a pointer to a string which describes the given error code. It will not work for the return codes 171 | MP\_YES and MP\_NO. 172 | 173 | \section{Data Types} 174 | 175 | To better work with LibTomFloat it helps to know what makes up the primary data type within LibTomFloat. 176 | 177 | \begin{alltt} 178 | typedef struct \{ 179 | mp_int mantissa; 180 | long radix, 181 | exp; 182 | \} mp_float; 183 | \end{alltt} 184 | 185 | The mp\_float data type is what all LibTomFloat functions will operate with and upon. The members of the structre are as follows: 186 | 187 | \begin{enumerate} 188 | \item The \textbf{mantissa} variable is a LibTomMath mp\_int that represents the digits of the float. Since it's a mp\_int it can accomodate 189 | any practical range of numbers. 190 | \item The \textbf{radix} variable is the precision desired for the mp\_float in bits. The higher the value the more precise (and slow) the 191 | calculations are. This value must be larger than two and ideally shouldn't be lower than what a ``double'' provides (55-bits of mantissa). 192 | \item The \textbf{exp} variable is the exponent associated with the number. 193 | \end{enumerate} 194 | 195 | \section{Function Organization} 196 | 197 | Many of the functions operate as their LibTomMath counterparts. That is the source operands are on the left and the destination is on the 198 | right. For instance: 199 | 200 | \begin{alltt} 201 | mpf_add(&a, &b, &c); /* c = a + b */ 202 | mpf_mul(&a, &a, &c); /* c = a * a */ 203 | mpf_div(&a, &b, &c); /* c = a / b */ 204 | \end{alltt} 205 | 206 | One major difference (and similar to LibTomPoly) is that the radix of the destination operation controls the radix of the internal computation and 207 | the final result. For instance, if $a$ and $b$ have a $24$--bit mantissa and $c$ has a $96$--bit mantissa then all three operations are performed 208 | with $96$--bits of precision. 209 | 210 | This is non--issue for algorithms such as addition or multiplication but more important for the series calculations such as division, inversion, 211 | square roots, etc. 212 | 213 | All functions normalize the result before returning. 214 | 215 | \section{Initialization} 216 | \subsection{Single Initializers} 217 | 218 | To initialize or clear a single mp\_float use the following two functions. 219 | 220 | \index{mpf\_init} \index{mpf\_clear} 221 | \begin{alltt} 222 | int mpf_init(mp_float *a, long radix); 223 | void mpf_clear(mp_float *a); 224 | \end{alltt} 225 | 226 | mpf\_init will initialize $a$ with the given radix to the default value of zero. mpf\_clear will free the memory used by the 227 | mp\_float. 228 | 229 | \begin{alltt} 230 | int main(void) 231 | \{ 232 | mp_float a; 233 | int err; 234 | 235 | /* initialize a mp_float with a 96-bit mantissa */ 236 | if ((err = mpf_init(&a, 96)) != MP_OKAY) \{ 237 | // error handle 238 | \} 239 | 240 | /* we now have a 96-bit mp_float ready ... do work */ 241 | 242 | /* done */ 243 | mpf_clear(&a); 244 | 245 | return EXIT_SUCCESS; 246 | \} 247 | \end{alltt} 248 | 249 | \subsection{Multiple Initializers} 250 | 251 | To initialize or clear multiple mp\_floats simultaneously use the following two functions. 252 | 253 | \index{mpf\_init\_multi} \index{mpf\_clear\_multi} 254 | \begin{alltt} 255 | int mpf_init_multi(long radix, mp_float *a, ...); 256 | void mpf_clear_multi(mp_float *a, ...); 257 | \end{alltt} 258 | 259 | mpf\_init\_multi will initialize a \textbf{NULL} terminated list of mp\_floats with the same given radix. mpf\_clear\_multi will free 260 | up a \textbf{NULL} terminated list of mp\_floats. 261 | 262 | \begin{alltt} 263 | int main(void) 264 | \{ 265 | mp_float a, b; 266 | int err; 267 | 268 | /* initialize two mp_floats with a 96-bit mantissa */ 269 | if ((err = mpf_init_multi(96, &a, &b, NULL)) != MP_OKAY) \{ 270 | // error handle 271 | \} 272 | 273 | /* we now have two 96-bit mp_floats ready ... do work */ 274 | 275 | /* done */ 276 | mpf_clear_multi(&a, &b, NULL); 277 | 278 | return EXIT_SUCCESS; 279 | \} 280 | \end{alltt} 281 | 282 | \subsection{Initialization of Copies} 283 | 284 | In order to initialize an mp\_float and make a copy of a source mp\_float the following function has been provided. 285 | 286 | \index{mpf\_init\_copy} 287 | \begin{alltt} 288 | int mpf_init_copy(mp_float *a, mp_float *b); 289 | \end{alltt} 290 | 291 | This will initialize $b$ and make it a copy of $a$. 292 | 293 | \begin{alltt} 294 | int main(void) 295 | \{ 296 | mp_float a, b; 297 | int err; 298 | 299 | /* initialize a mp_float with a 96-bit mantissa */ 300 | if ((err = mpf_init(&a, 96)) != MP_OKAY) \{ 301 | // error handle 302 | \} 303 | 304 | /* we now have a 96-bit mp_float ready ... do work */ 305 | 306 | /* now make our copy */ 307 | if ((err = mpf_init_copy(&a, &b)) != MP_OKAY) \{ 308 | // error handle 309 | \} 310 | 311 | /* now b is a copy of a */ 312 | 313 | /* done */ 314 | mpf_clear_multi(&a, &b, NULL); 315 | 316 | return EXIT_SUCCESS; 317 | \} 318 | \end{alltt} 319 | 320 | \section{Data Movement} 321 | \subsection{Copying} 322 | In order to copy one mp\_float into another mp\_float the following function has been provided. 323 | 324 | \index{mpf\_copy} 325 | \begin{alltt} 326 | int mpf_copy(mp_float *src, mp_float *dest); 327 | \end{alltt} 328 | This will copy the mp\_float from $src$ into $dest$. Note that the final radix of $dest$ will be that of $src$. 329 | 330 | \begin{alltt} 331 | int main(void) 332 | \{ 333 | mp_float a, b; 334 | int err; 335 | 336 | /* initialize two mp_floats with a 96-bit mantissa */ 337 | if ((err = mpf_init_multi(96, &a, &b, NULL)) != MP_OKAY) \{ 338 | // error handle 339 | \} 340 | 341 | /* we now have two 96-bit mp_floats ready ... do work */ 342 | 343 | /* put a into b */ 344 | if ((err = mpf_copy(&a, &b)) != MP_OKAY) \{ 345 | // error handle 346 | \} 347 | 348 | /* done */ 349 | mpf_clear_multi(&a, &b, NULL); 350 | 351 | return EXIT_SUCCESS; 352 | \} 353 | \end{alltt} 354 | 355 | \subsection{Exchange} 356 | 357 | To exchange the contents of two mp\_float data types use this f00. 358 | 359 | \index{mpf\_exch} 360 | \begin{alltt} 361 | void mpf_exch(mp_float *a, mp_float *b); 362 | \end{alltt} 363 | 364 | This will swap the contents of $a$ and $b$. 365 | 366 | \chapter{Basic Operations} 367 | \section{Normalization} 368 | 369 | \subsection{Simple Normalization} 370 | Normalization is not required by the user unless they fiddle with the mantissa on their own. If that's the case you can 371 | use this function. 372 | \index{mpf\_normalize} 373 | \begin{alltt} 374 | int mpf_normalize(mp_float *a); 375 | \end{alltt} 376 | This will fix up the mantissa of $a$ such that the leading bit is one (if the number is non--zero). 377 | 378 | \subsection{Normalize to New Radix} 379 | In order to change the radix of a non--zero number you must call this function. 380 | 381 | \index{mpf\_normalize\_to} 382 | \begin{alltt} 383 | int mpf_normalize_to(mp_float *a, long radix); 384 | \end{alltt} 385 | This will change the radix of $a$ then normalize it accordingly. 386 | 387 | \section{Constants} 388 | 389 | \subsection{Quick Constants} 390 | The following are helpers for various numbers. 391 | 392 | \index{mpf\_const\_0} \index{mpf\_const\_d} \index{mpf\_const\_ln\_d} \index{mpf\_const\_sqrt\_d} 393 | \begin{alltt} 394 | int mpf_const_0(mp_float *a); 395 | int mpf_const_d(mp_float *a, long d); 396 | int mpf_const_ln_d(mp_float *a, long b); 397 | int mpf_const_sqrt_d(mp_float *a, long b); 398 | \end{alltt} 399 | 400 | mpf\_const\_0 will set $a$ to a valid representation of zero. mpf\_const\_d will set $a$ to a valid signed representation of 401 | $d$. mpf\_const\_ln\_d will set $a$ to the natural logarithm of $b$. mpf\_const\_sqrt\_d will set $a$ to the square root of 402 | $b$. 403 | 404 | The next set of constants (fig. \ref{fig:const}) compute the standard constants as defined in ``math.h''. 405 | \begin{figure}[here] 406 | \begin{center} 407 | \begin{tabular}{|l|l|} 408 | \hline \textbf{Function Name} & \textbf{Value} \\ 409 | mpf\_const\_e & $e$ \\ 410 | mpf\_const\_l2e & log$_2(e)$ \\ 411 | mpf\_const\_l10e & log$_{10}(e)$ \\ 412 | mpf\_const\_le2 & ln$(2)$ \\ 413 | mpf\_const\_pi & $\pi$ \\ 414 | mpf\_const\_pi2 & $\pi / 2$ \\ 415 | mpf\_const\_pi4 & $\pi / 4$ \\ 416 | mpf\_const\_1pi & $1 / \pi$ \\ 417 | mpf\_const\_2pi & $2 / \pi$ \\ 418 | mpf\_const\_2rpi & $2 / \sqrt{\pi}$ \\ 419 | mpf\_const\_r2 & ${\sqrt{2}}$ \\ 420 | mpf\_const\_1r2 & $1 / {\sqrt{2}}$ \\ 421 | \hline 422 | \end{tabular} 423 | \end{center} 424 | \caption{LibTomFloat Constants.} 425 | \label{fig:const} 426 | \end{figure} 427 | 428 | All of these functions accept a single input argument. They calculate the constant at run--time using the precision specified in the input 429 | argument. 430 | 431 | \begin{alltt} 432 | int main(void) 433 | \{ 434 | mp_float a; 435 | int err; 436 | 437 | /* initialize a mp_float with a 96-bit mantissa */ 438 | if ((err = mpf_init(&a, 96)) != MP_OKAY) \{ 439 | // error handle 440 | \} 441 | 442 | /* let's find out what the square root of 2 is (approximately ;-)) */ 443 | if ((err = mpf_const_r2(&a)) != MP_OKAY) \{ 444 | // error handle 445 | \} 446 | 447 | /* now a has sqrt(2) to 96-bits of precision */ 448 | 449 | /* done */ 450 | mpf_clear(&a); 451 | 452 | return EXIT_SUCCESS; 453 | \} 454 | \end{alltt} 455 | 456 | \section{Sign Manipulation} 457 | To manipulate the sign of a mp\_float use the following two functions. 458 | 459 | \index{mpf\_abs} \index{mpf\_neg} 460 | \begin{alltt} 461 | int mpf_abs(mp_float *a, mp_float *b); 462 | int mpf_neg(mp_float *a, mp_float *b); 463 | \end{alltt} 464 | 465 | mpf\_abs computes the absolute of $a$ and stores it in $b$. mpf\_neg computes the negative of $a$ and stores it in $b$. Note that the numbers 466 | are normalized to the radix of $b$ before being returned. 467 | 468 | \begin{alltt} 469 | int main(void) 470 | \{ 471 | mp_float a; 472 | int err; 473 | 474 | /* initialize a mp_float with a 96-bit mantissa */ 475 | if ((err = mpf_init(&a, 96)) != MP_OKAY) \{ 476 | // error handle 477 | \} 478 | 479 | /* let's find out what the square root of 2 is (approximately ;-)) */ 480 | if ((err = mpf_const_r2(&a)) != MP_OKAY) \{ 481 | // error handle 482 | \} 483 | 484 | /* now make it negative */ 485 | if ((err = mpf_neg(&a, &a)) != MP_OKAY) \{ 486 | // error handle 487 | \} 488 | 489 | /* done */ 490 | mpf_clear(&a); 491 | 492 | return EXIT_SUCCESS; 493 | \} 494 | \end{alltt} 495 | 496 | \chapter{Basic Algebra} 497 | \section{Algebraic Operators} 498 | 499 | The following four functions provide for basic addition, subtraction, multiplication and division of mp\_float numbers. 500 | 501 | \index{mpf\_add} \index{mpf\_sub} \index{mpf\_mul} \index{mpf\_div} 502 | \begin{alltt} 503 | int mpf_add(mp_float *a, mp_float *b, mp_float *c); 504 | int mpf_sub(mp_float *a, mp_float *b, mp_float *c); 505 | int mpf_mul(mp_float *a, mp_float *b, mp_float *c); 506 | int mpf_div(mp_float *a, mp_float *b, mp_float *c); 507 | \end{alltt} 508 | These functions perform their respective operations on $a$ and $b$ and store the result in $c$. 509 | 510 | \subsection{Additional Interfaces} 511 | In order to make programming easier with the library the following four functions have been provided as well. 512 | 513 | \index{mpf\_add\_d} \index{mpf\_sub\_d} \index{mpf\_mul\_d} \index{mpf\_div\_d} 514 | \begin{alltt} 515 | int mpf_add_d(mp_float *a, long b, mp_float *c); 516 | int mpf_sub_d(mp_float *a, long b, mp_float *c); 517 | int mpf_mul_d(mp_float *a, long b, mp_float *c); 518 | int mpf_div_d(mp_float *a, long b, mp_float *c); 519 | \end{alltt} 520 | These work like the previous four functions except the second argument is a ``long'' type. This allow operations with 521 | mixed mp\_float and integer types (specifically constants) to be performed relatively easy. 522 | 523 | \textit{I will put an example of all op/op\_d functions here...} 524 | 525 | \subsection{Additional Operators} 526 | The next three functions round out the simple algebraic operators. 527 | 528 | \index{mpf\_mul\_2} \index{mpf\_div\_2} \index{mpf\_sqr} 529 | \begin{alltt} 530 | int mpf_mul_2(mp_float *a, mp_float *b); 531 | int mpf_div_2(mp_float *a, mp_float *b); 532 | int mpf_sqr(mp_float *a, mp_float *b); 533 | \end{alltt} 534 | 535 | mpf\_mul\_2 and mpf\_div\_2 multiply (or divide) $a$ by two and store it in $b$. mpf\_sqr squares $a$ and stores it in $b$. mpf\_sqr is 536 | faster than using mpf\_mul for squaring mp\_floats. 537 | 538 | \section{Comparisons} 539 | To compare two mp\_floats the following function can be used. 540 | \index{mp\_cmp} 541 | \begin{alltt} 542 | int mpf_cmp(mp_float *a, mp_float *b); 543 | \end{alltt} 544 | This will compare $a$ to $b$ and return one of the LibTomMath comparison flags. Simply put, if $a$ is larger than $b$ it returns 545 | MP\_GT. If $a$ is smaller than $b$ it returns MP\_LT, otherwise it returns MP\_EQ. The comparison is signed. 546 | 547 | To quickly compare an mp\_float to a ``long'' the following is provided. 548 | 549 | \index{mpf\_cmp\_d} 550 | \begin{alltt} 551 | int mpf_cmp_d(mp_float *a, long b, int *res); 552 | \end{alltt} 553 | 554 | Which compares $a$ to $b$ and stores the result in $res$. This function can fail which is unlike the digit compare from LibTomMath. 555 | 556 | \chapter{Advanced Algebra} 557 | \section{Powers} 558 | \subsection{Exponential} 559 | The following function computes $exp(x)$ otherwise known as $e^x$. 560 | 561 | \index{mpf\_exp} 562 | \begin{alltt} 563 | int mpf_exp(mp_float *a, mp_float *b); 564 | \end{alltt} 565 | 566 | This computes $e^a$ and stores it into $b$. 567 | 568 | \subsection{Power Operator} 569 | The following function computes the generic $a^b$ operation. 570 | 571 | \index{mpf\_pow} 572 | \begin{alltt} 573 | int mpf_pow(mp_float *a, mp_float *b, mp_float *c); 574 | \end{alltt} 575 | This computes $a^b$ and stores the result in $c$. 576 | 577 | \subsection{Natural Logarithm} 578 | 579 | The following function computes the natural logarithm. 580 | \index{mpf\_ln} 581 | \begin{alltt} 582 | int mpf_ln(mp_float *a, mp_float *b); 583 | \end{alltt} 584 | This computes $ln(a)$ and stores the result in $b$. 585 | 586 | \section{Inversion and Roots} 587 | 588 | \subsection{Inverse Square Root} 589 | The following function computes $1 / \sqrt{x}$. 590 | 591 | \index{mpf\_invsqrt} 592 | \begin{alltt} 593 | int mpf_invsqrt(mp_float *a, mp_float *b); 594 | \end{alltt} 595 | 596 | This computes $1 / \sqrt{a}$ and stores the result in $b$. 597 | 598 | \subsection{Inverse} 599 | 600 | The following function computes $1 / x$. 601 | \index{mpf\_inv} 602 | \begin{alltt} 603 | int mpf_inv(mp_float *a, mp_float *b); 604 | \end{alltt} 605 | This computes $1/a$ and stores the result in $b$. 606 | 607 | 608 | \subsection{Square Root} 609 | 610 | The following function computes $\sqrt{x}$. 611 | 612 | \index{mpf\_sqrt} 613 | \begin{alltt} 614 | int mpf_sqrt(mp_float *a, mp_float *b); 615 | \end{alltt} 616 | 617 | This computes $\sqrt{a}$ and stores the result in $b$. 618 | 619 | \section{Trigonometry Functions} 620 | The following functions compute various trigonometric functions. All inputs are assumed to be in radians. 621 | 622 | \index{mpf\_cos} \index{mpf\_sin} \index{mpf\_tan} \index{mpf\_acos} \index{mpf\_asin} \index{mpf\_atan} 623 | \begin{alltt} 624 | int mpf_cos(mp_float *a, mp_float *b); 625 | int mpf_sin(mp_float *a, mp_float *b); 626 | int mpf_tan(mp_float *a, mp_float *b); 627 | int mpf_acos(mp_float *a, mp_float *b); 628 | int mpf_asin(mp_float *a, mp_float *b); 629 | int mpf_atan(mp_float *a, mp_float *b); 630 | \end{alltt} 631 | 632 | These all compute their respective trigonometric function on $a$ and store the result in $b$. The ``a'' prefix stands for ``arc'' or more 633 | commonly known as inverse. 634 | 635 | \input{float.ind} 636 | 637 | \end{document} 638 | -------------------------------------------------------------------------------- /makefile: -------------------------------------------------------------------------------- 1 | #GCC makefile for LibTomFloat 2 | # 3 | #Tom St Denis 4 | 5 | default: libtomfloat.a 6 | 7 | CFLAGS += -Os -Wall -W -I./ 8 | 9 | VERSION=0.02 10 | 11 | #default files to install 12 | LIBNAME=libtomfloat.a 13 | HEADERS=tomfloat.h 14 | 15 | #LIBPATH-The directory for libtomfloat to be installed to. 16 | #INCPATH-The directory to install the header files for libtomfloat. 17 | #DATAPATH-The directory to install the pdf docs. 18 | DESTDIR= 19 | LIBPATH=/usr/lib 20 | INCPATH=/usr/include 21 | DATAPATH=/usr/share/doc/libtomfloat/pdf 22 | 23 | 24 | OBJECTS = \ 25 | mpf_init.o mpf_clear.o mpf_init_multi.o mpf_clear_multi.o mpf_init_copy.o \ 26 | \ 27 | mpf_copy.o mpf_exch.o mpf_abs.o mpf_neg.o \ 28 | \ 29 | mpf_cmp.o mpf_cmp_d.o \ 30 | \ 31 | mpf_normalize.o mpf_normalize_to.o mpf_iterations.o \ 32 | \ 33 | mpf_const_0.o mpf_const_1r2.o mpf_const_2rpi.o mpf_const_e.o \ 34 | mpf_const_l2e.o mpf_const_pi.o mpf_const_pi4.o mpf_const_1pi.o \ 35 | mpf_const_2pi.o mpf_const_d.o mpf_const_l10e.o mpf_const_le2.o \ 36 | mpf_const_pi2.o mpf_const_r2.o mpf_const_ln_d.o \ 37 | \ 38 | mpf_mul_2.o mpf_div_2.o mpf_add.o mpf_sub.o mpf_mul.o mpf_sqr.o mpf_div.o \ 39 | mpf_add_d.o mpf_sub_d.o mpf_mul_d.o mpf_div_d.o \ 40 | \ 41 | mpf_invsqrt.o mpf_inv.o mpf_exp.o mpf_sqrt.o mpf_pow.o mpf_ln.o \ 42 | \ 43 | mpf_cos.o mpf_sin.o mpf_tan.o mpf_acos.o mpf_asin.o mpf_atan.o 44 | 45 | libtomfloat.a: $(OBJECTS) 46 | $(AR) $(ARFLAGS) libtomfloat.a $(OBJECTS) 47 | ranlib libtomfloat.a 48 | 49 | ex1: libtomfloat.a demos/ex1.o 50 | $(CC) demos/ex1.o libtomfloat.a -ltommath -o ex1 51 | 52 | #LTF user manual 53 | mandvi: float.tex 54 | echo "hello" > float.ind 55 | latex float > /dev/null 56 | latex float > /dev/null 57 | makeindex float 58 | latex float > /dev/null 59 | 60 | #LTF user manual [pdf] 61 | manual: mandvi 62 | pdflatex float >/dev/null 63 | rm -f float.aux float.dvi float.log float.idx float.lof float.out float.toc 64 | 65 | install: libtomfloat.a 66 | install -d -g root -o root $(DESTDIR)$(LIBPATH) 67 | install -d -g root -o root $(DESTDIR)$(INCPATH) 68 | install -g root -o root $(LIBNAME) $(DESTDIR)$(LIBPATH) 69 | install -g root -o root $(HEADERS) $(DESTDIR)$(INCPATH) 70 | 71 | clean: 72 | rm -f $(OBJECTS) libtomfloat.a *~ demos/*.o demos/*~ ex1 73 | rm -f float.aux float.dvi float.log float.idx float.lof float.out float.toc float.ilg float.ind float.pdf 74 | 75 | zipup: clean manual 76 | cd .. ; rm -rf ltf* libtomfloat-$(VERSION) ; mkdir libtomfloat-$(VERSION) ; \ 77 | cp -R ./libtomfloat/* ./libtomfloat-$(VERSION)/ ; \ 78 | tar -c libtomfloat-$(VERSION)/* | bzip2 -9vvc > ltf-$(VERSION).tar.bz2 ; \ 79 | zip -9 -r ltf-$(VERSION).zip libtomfloat-$(VERSION)/* 80 | -------------------------------------------------------------------------------- /mpf_abs.c: -------------------------------------------------------------------------------- 1 | /* LibTomFloat, multiple-precision floating-point library 2 | * 3 | * LibTomFloat is a library that provides multiple-precision 4 | * floating-point artihmetic as well as trigonometric functionality. 5 | * 6 | * This library requires the public domain LibTomMath to be installed. 7 | * 8 | * This library is free for all purposes without any express 9 | * gurantee it works 10 | * 11 | * Tom St Denis, tomstdenis@iahu.ca, http://float.libtomcrypt.org 12 | */ 13 | #include 14 | 15 | int mpf_abs(mp_float *a, mp_float *b) 16 | { 17 | int err; 18 | if ((err = mp_abs((&a->mantissa), &(b->mantissa))) != MP_OKAY) { 19 | return err; 20 | } 21 | b->exp = a->exp; 22 | return mpf_normalize(b); 23 | } 24 | -------------------------------------------------------------------------------- /mpf_acos.c: -------------------------------------------------------------------------------- 1 | /* LibTomFloat, multiple-precision floating-point library 2 | * 3 | * LibTomFloat is a library that provides multiple-precision 4 | * floating-point artihmetic as well as trigonometric functionality. 5 | * 6 | * This library requires the public domain LibTomMath to be installed. 7 | * 8 | * This library is free for all purposes without any express 9 | * gurantee it works 10 | * 11 | * Tom St Denis, tomstdenis@iahu.ca, http://float.libtomcrypt.org 12 | */ 13 | #include 14 | 15 | int mpf_acos(mp_float *a, mp_float *b) 16 | { 17 | } 18 | -------------------------------------------------------------------------------- /mpf_add.c: -------------------------------------------------------------------------------- 1 | /* LibTomFloat, multiple-precision floating-point library 2 | * 3 | * LibTomFloat is a library that provides multiple-precision 4 | * floating-point artihmetic as well as trigonometric functionality. 5 | * 6 | * This library requires the public domain LibTomMath to be installed. 7 | * 8 | * This library is free for all purposes without any express 9 | * gurantee it works 10 | * 11 | * Tom St Denis, tomstdenis@iahu.ca, http://float.libtomcrypt.org 12 | */ 13 | #include 14 | 15 | int mpf_add(mp_float *a, mp_float *b, mp_float *c) 16 | { 17 | int err; 18 | mp_float tmp, *other; 19 | long diff; 20 | 21 | if (mpf_iszero(a)) { 22 | diff = c->radix; 23 | if ((err = mpf_copy(b, c)) != MP_OKAY) { 24 | return err; 25 | } 26 | return mpf_normalize_to(c, diff); 27 | } else if (mpf_iszero(b)) { 28 | diff = c->radix; 29 | if ((err = mpf_copy(a, c)) != MP_OKAY) { 30 | return err; 31 | } 32 | return mpf_normalize_to(c, diff); 33 | } 34 | 35 | if (a->exp < b->exp) { 36 | /* tmp == a normalize to b's exp */ 37 | if ((err = mpf_init_copy(a, &tmp)) != MP_OKAY) { 38 | return err; 39 | } 40 | 41 | /* now make tmp.exp == b.exp by dividing tmp by 2^(b.exp - tmp.exp) */ 42 | diff = b->exp - tmp.exp; 43 | tmp.exp = b->exp; 44 | if ((err = mp_div_2d(&(tmp.mantissa), diff, (&tmp.mantissa), NULL)) != MP_OKAY) { goto __TMP; } 45 | 46 | /* other arg */ 47 | other = b; 48 | } else { 49 | /* tmp == b normalize to a's radix */ 50 | if ((err = mpf_init_copy(b, &tmp)) != MP_OKAY) { 51 | return err; 52 | } 53 | 54 | /* now make tmp.exp == a.exp by dividing tmp by 2^(a.exp - tmp.exp) */ 55 | diff = a->exp - tmp.exp; 56 | tmp.exp = a->exp; 57 | if ((err = mp_div_2d(&(tmp.mantissa), diff, (&tmp.mantissa), NULL)) != MP_OKAY) { goto __TMP; } 58 | 59 | /* other arg */ 60 | other = a; 61 | } 62 | 63 | /* perform addition, set the exponent and then normalize */ 64 | if ((err = mp_add(&(tmp.mantissa), &(other->mantissa), &(c->mantissa))) != MP_OKAY) { goto __TMP; } 65 | c->exp = other->exp; 66 | err = mpf_normalize(c); 67 | 68 | __TMP: mpf_clear(&tmp); 69 | return err; 70 | } 71 | -------------------------------------------------------------------------------- /mpf_add_d.c: -------------------------------------------------------------------------------- 1 | /* LibTomFloat, multiple-precision floating-point library 2 | * 3 | * LibTomFloat is a library that provides multiple-precision 4 | * floating-point artihmetic as well as trigonometric functionality. 5 | * 6 | * This library requires the public domain LibTomMath to be installed. 7 | * 8 | * This library is free for all purposes without any express 9 | * gurantee it works 10 | * 11 | * Tom St Denis, tomstdenis@iahu.ca, http://float.libtomcrypt.org 12 | */ 13 | #include 14 | 15 | int mpf_add_d(mp_float *a, long b, mp_float *c) 16 | { 17 | int err; 18 | mp_float tmp; 19 | 20 | if ((err = mpf_init(&tmp, c->radix)) != MP_OKAY) { 21 | return err; 22 | } 23 | 24 | if ((err = mpf_const_d(&tmp, b)) != MP_OKAY) { goto __ERR; } 25 | err = mpf_add(a, &tmp, c); 26 | 27 | __ERR: 28 | mpf_clear(&tmp); 29 | return err; 30 | } 31 | 32 | -------------------------------------------------------------------------------- /mpf_asin.c: -------------------------------------------------------------------------------- 1 | /* LibTomFloat, multiple-precision floating-point library 2 | * 3 | * LibTomFloat is a library that provides multiple-precision 4 | * floating-point artihmetic as well as trigonometric functionality. 5 | * 6 | * This library requires the public domain LibTomMath to be installed. 7 | * 8 | * This library is free for all purposes without any express 9 | * gurantee it works 10 | * 11 | * Tom St Denis, tomstdenis@iahu.ca, http://float.libtomcrypt.org 12 | */ 13 | #include 14 | 15 | int mpf_asin(mp_float *a, mp_float *b) 16 | { 17 | } 18 | -------------------------------------------------------------------------------- /mpf_atan.c: -------------------------------------------------------------------------------- 1 | /* LibTomFloat, multiple-precision floating-point library 2 | * 3 | * LibTomFloat is a library that provides multiple-precision 4 | * floating-point artihmetic as well as trigonometric functionality. 5 | * 6 | * This library requires the public domain LibTomMath to be installed. 7 | * 8 | * This library is free for all purposes without any express 9 | * gurantee it works 10 | * 11 | * Tom St Denis, tomstdenis@iahu.ca, http://float.libtomcrypt.org 12 | */ 13 | #include 14 | 15 | /* y = y - (tan(y) - x)/(tan(y+0.1)-tan(x)) */ 16 | 17 | int mpf_atan(mp_float *a, mp_float *b) 18 | { 19 | mp_float oldval, tmp, tmpx, res, sqr; 20 | int oddeven, ires, err, itts; 21 | long n; 22 | 23 | /* ensure -1 <= a <= 1 */ 24 | if ((err = mpf_cmp_d(a, -1, &ires)) != MP_OKAY) { 25 | return err; 26 | } 27 | if (ires == MP_LT) { 28 | return MP_VAL; 29 | } 30 | 31 | if ((err = mpf_cmp_d(a, 1, &ires)) != MP_OKAY) { 32 | return err; 33 | } 34 | if (ires == MP_GT) { 35 | return MP_VAL; 36 | } 37 | 38 | /* easy out if a == 0 */ 39 | if (mpf_iszero(a) == MP_YES) { 40 | return mpf_const_d(b, 1); 41 | } 42 | 43 | /* now a != 0 */ 44 | 45 | /* initialize temps */ 46 | if ((err = mpf_init_multi(b->radix, &oldval, &tmpx, &tmp, &res, &sqr, NULL)) != MP_OKAY) { 47 | return err; 48 | } 49 | 50 | /* initlialize temps */ 51 | /* res = 0 */ 52 | /* tmpx = 1/a */ 53 | if ((err = mpf_inv(a, &tmpx)) != MP_OKAY) { goto __ERR; } 54 | 55 | /* sqr = a^2 */ 56 | if ((err = mpf_sqr(a, &sqr)) != MP_OKAY) { goto __ERR; } 57 | 58 | /* this is the denom counter. Goes up by two per pass */ 59 | n = 1; 60 | 61 | /* we alternate between adding and subtracting */ 62 | oddeven = 0; 63 | 64 | /* get number of iterations */ 65 | itts = mpf_iterations(b); 66 | 67 | while (itts-- > 0) { 68 | if ((err = mpf_copy(&res, &oldval)) != MP_OKAY) { goto __ERR; } 69 | 70 | /* compute 1/(2n-1) */ 71 | if ((err = mpf_const_d(&tmp, (2*n++ - 1))) != MP_OKAY) { goto __ERR; } 72 | if ((err = mpf_inv(&tmp, &tmp)) != MP_OKAY) { goto __ERR; } 73 | 74 | /* now multiply a into tmpx twice */ 75 | if ((err = mpf_mul(&tmpx, &sqr, &tmpx)) != MP_OKAY) { goto __ERR; } 76 | 77 | /* now multiply the two */ 78 | if ((err = mpf_mul(&tmpx, &tmp, &tmp)) != MP_OKAY) { goto __ERR; } 79 | 80 | /* now depending on if this is even or odd we add/sub */ 81 | oddeven ^= 1; 82 | if (oddeven == 1) { 83 | if ((err = mpf_add(&res, &tmp, &res)) != MP_OKAY) { goto __ERR; } 84 | } else { 85 | if ((err = mpf_sub(&res, &tmp, &res)) != MP_OKAY) { goto __ERR; } 86 | } 87 | 88 | if (mpf_cmp(&oldval, &res) == MP_EQ) { 89 | break; 90 | } 91 | } 92 | mpf_exch(&res, b); 93 | __ERR: mpf_clear_multi(&oldval, &tmpx, &tmp, &res, &sqr, NULL); 94 | return err; 95 | 96 | } 97 | -------------------------------------------------------------------------------- /mpf_clear.c: -------------------------------------------------------------------------------- 1 | /* LibTomFloat, multiple-precision floating-point library 2 | * 3 | * LibTomFloat is a library that provides multiple-precision 4 | * floating-point artihmetic as well as trigonometric functionality. 5 | * 6 | * This library requires the public domain LibTomMath to be installed. 7 | * 8 | * This library is free for all purposes without any express 9 | * gurantee it works 10 | * 11 | * Tom St Denis, tomstdenis@iahu.ca, http://float.libtomcrypt.org 12 | */ 13 | #include 14 | 15 | void mpf_clear(mp_float *a) 16 | { 17 | mp_clear(&(a->mantissa)); 18 | a->radix = 0; 19 | a->exp = 0; 20 | } 21 | 22 | -------------------------------------------------------------------------------- /mpf_clear_multi.c: -------------------------------------------------------------------------------- 1 | /* LibTomFloat, multiple-precision floating-point library 2 | * 3 | * LibTomFloat is a library that provides multiple-precision 4 | * floating-point artihmetic as well as trigonometric functionality. 5 | * 6 | * This library requires the public domain LibTomMath to be installed. 7 | * 8 | * This library is free for all purposes without any express 9 | * gurantee it works 10 | * 11 | * Tom St Denis, tomstdenis@iahu.ca, http://float.libtomcrypt.org 12 | */ 13 | #include 14 | #include 15 | 16 | void mpf_clear_multi(mp_float *a, ...) 17 | { 18 | mp_float* next_mp = a; 19 | va_list args; 20 | va_start(args, a); 21 | while (next_mp != NULL) { 22 | mpf_clear(next_mp); 23 | next_mp = va_arg(args, mp_float*); 24 | } 25 | va_end(args); 26 | } 27 | -------------------------------------------------------------------------------- /mpf_cmp.c: -------------------------------------------------------------------------------- 1 | /* LibTomFloat, multiple-precision floating-point library 2 | * 3 | * LibTomFloat is a library that provides multiple-precision 4 | * floating-point artihmetic as well as trigonometric functionality. 5 | * 6 | * This library requires the public domain LibTomMath to be installed. 7 | * 8 | * This library is free for all purposes without any express 9 | * gurantee it works 10 | * 11 | * Tom St Denis, tomstdenis@iahu.ca, http://float.libtomcrypt.org 12 | */ 13 | #include 14 | 15 | int mpf_cmp(mp_float *a, mp_float *b) 16 | { 17 | int za, zb, sa, sb; 18 | 19 | /* if one is zero than we early out */ 20 | za = mp_iszero(&(a->mantissa)); 21 | sa = a->mantissa.sign; 22 | zb = mp_iszero(&(b->mantissa)); 23 | sb = b->mantissa.sign; 24 | 25 | if (za == MP_YES && zb == MP_NO) { 26 | /* result depends on b */ 27 | if (sb == MP_NEG) { 28 | return MP_GT; 29 | } else { 30 | return MP_LT; 31 | } 32 | } else if (za == MP_NO && zb == MP_YES) { 33 | /* result depends on a */ 34 | if (sa == MP_NEG) { 35 | return MP_LT; 36 | } else { 37 | return MP_GT; 38 | } 39 | } 40 | 41 | /* compare the signs */ 42 | if (sa == MP_NEG && sb == MP_ZPOS) { 43 | return MP_LT; 44 | } else if (sa == MP_ZPOS && sb == MP_NEG) { 45 | return MP_GT; 46 | } 47 | 48 | /* they're both non-zero, the same sign and normalized, compare the exponents */ 49 | if (a->exp > b->exp) { 50 | return (sa == MP_NEG) ? MP_LT : MP_GT; 51 | } else if (a->exp < b->exp) { 52 | return (sa == MP_NEG) ? MP_GT : MP_LT; 53 | } 54 | 55 | /* same exponent and sign, compare mantissa */ 56 | return mp_cmp(&(a->mantissa), &(b->mantissa)); 57 | } 58 | 59 | -------------------------------------------------------------------------------- /mpf_cmp_d.c: -------------------------------------------------------------------------------- 1 | /* LibTomFloat, multiple-precision floating-point library 2 | * 3 | * LibTomFloat is a library that provides multiple-precision 4 | * floating-point artihmetic as well as trigonometric functionality. 5 | * 6 | * This library requires the public domain LibTomMath to be installed. 7 | * 8 | * This library is free for all purposes without any express 9 | * gurantee it works 10 | * 11 | * Tom St Denis, tomstdenis@iahu.ca, http://float.libtomcrypt.org 12 | */ 13 | #include 14 | 15 | int mpf_cmp_d(mp_float *a, long b, int *res) 16 | { 17 | int err; 18 | mp_float tmp; 19 | 20 | if ((err = mpf_init(&tmp, a->radix)) != MP_OKAY) { 21 | return err; 22 | } 23 | 24 | if ((err = mpf_const_d(&tmp, b)) != MP_OKAY) { goto __ERR; } 25 | *res = mpf_cmp(a, &tmp); 26 | 27 | __ERR: 28 | mpf_clear(&tmp); 29 | return err; 30 | } 31 | -------------------------------------------------------------------------------- /mpf_const_0.c: -------------------------------------------------------------------------------- 1 | /* LibTomFloat, multiple-precision floating-point library 2 | * 3 | * LibTomFloat is a library that provides multiple-precision 4 | * floating-point artihmetic as well as trigonometric functionality. 5 | * 6 | * This library requires the public domain LibTomMath to be installed. 7 | * 8 | * This library is free for all purposes without any express 9 | * gurantee it works 10 | * 11 | * Tom St Denis, tomstdenis@iahu.ca, http://float.libtomcrypt.org 12 | */ 13 | #include 14 | 15 | /* zero defined as 0 * 2^1 */ 16 | int mpf_const_0(mp_float *a) 17 | { 18 | mp_zero(&(a->mantissa)); 19 | a->exp = 1; 20 | return MP_OKAY; 21 | } 22 | 23 | -------------------------------------------------------------------------------- /mpf_const_1pi.c: -------------------------------------------------------------------------------- 1 | /* LibTomFloat, multiple-precision floating-point library 2 | * 3 | * LibTomFloat is a library that provides multiple-precision 4 | * floating-point artihmetic as well as trigonometric functionality. 5 | * 6 | * This library requires the public domain LibTomMath to be installed. 7 | * 8 | * This library is free for all purposes without any express 9 | * gurantee it works 10 | * 11 | * Tom St Denis, tomstdenis@iahu.ca, http://float.libtomcrypt.org 12 | */ 13 | #include 14 | 15 | int mpf_const_1pi(mp_float *a) 16 | { 17 | int err; 18 | if ((err = mpf_const_pi(a)) != MP_OKAY) { 19 | return err; 20 | } 21 | return mpf_inv(a, a); 22 | } 23 | /* 1/Pi */ 24 | 25 | -------------------------------------------------------------------------------- /mpf_const_1r2.c: -------------------------------------------------------------------------------- 1 | /* LibTomFloat, multiple-precision floating-point library 2 | * 3 | * LibTomFloat is a library that provides multiple-precision 4 | * floating-point artihmetic as well as trigonometric functionality. 5 | * 6 | * This library requires the public domain LibTomMath to be installed. 7 | * 8 | * This library is free for all purposes without any express 9 | * gurantee it works 10 | * 11 | * Tom St Denis, tomstdenis@iahu.ca, http://float.libtomcrypt.org 12 | */ 13 | #include 14 | 15 | int mpf_const_1r2(mp_float *a) 16 | { 17 | int err; 18 | if ((err = mpf_const_r2(a)) != MP_OKAY) { 19 | return err; 20 | } 21 | return mpf_inv(a, a); 22 | } 23 | /* 1/sqrt(2) */ 24 | 25 | -------------------------------------------------------------------------------- /mpf_const_2pi.c: -------------------------------------------------------------------------------- 1 | /* LibTomFloat, multiple-precision floating-point library 2 | * 3 | * LibTomFloat is a library that provides multiple-precision 4 | * floating-point artihmetic as well as trigonometric functionality. 5 | * 6 | * This library requires the public domain LibTomMath to be installed. 7 | * 8 | * This library is free for all purposes without any express 9 | * gurantee it works 10 | * 11 | * Tom St Denis, tomstdenis@iahu.ca, http://float.libtomcrypt.org 12 | */ 13 | #include 14 | 15 | int mpf_const_2pi(mp_float *a) 16 | { 17 | int err; 18 | if ((err = mpf_const_pi(a)) != MP_OKAY) { 19 | return err; 20 | } 21 | if ((err = mpf_inv(a, a)) != MP_OKAY) { 22 | return err; 23 | } 24 | return mpf_mul_2(a, a); 25 | } 26 | /* 2/Pi */ 27 | 28 | -------------------------------------------------------------------------------- /mpf_const_2rpi.c: -------------------------------------------------------------------------------- 1 | /* LibTomFloat, multiple-precision floating-point library 2 | * 3 | * LibTomFloat is a library that provides multiple-precision 4 | * floating-point artihmetic as well as trigonometric functionality. 5 | * 6 | * This library requires the public domain LibTomMath to be installed. 7 | * 8 | * This library is free for all purposes without any express 9 | * gurantee it works 10 | * 11 | * Tom St Denis, tomstdenis@iahu.ca, http://float.libtomcrypt.org 12 | */ 13 | #include 14 | 15 | int mpf_const_2rpi(mp_float *a) 16 | { 17 | int err; 18 | if ((err = mpf_const_pi(a)) != MP_OKAY) { 19 | return err; 20 | } 21 | if ((err = mpf_invsqrt(a, a)) != MP_OKAY) { 22 | return err; 23 | } 24 | return mpf_mul_2(a, a); 25 | } 26 | /* 2/sqrt(Pi) */ 27 | 28 | -------------------------------------------------------------------------------- /mpf_const_d.c: -------------------------------------------------------------------------------- 1 | /* LibTomFloat, multiple-precision floating-point library 2 | * 3 | * LibTomFloat is a library that provides multiple-precision 4 | * floating-point artihmetic as well as trigonometric functionality. 5 | * 6 | * This library requires the public domain LibTomMath to be installed. 7 | * 8 | * This library is free for all purposes without any express 9 | * gurantee it works 10 | * 11 | * Tom St Denis, tomstdenis@iahu.ca, http://float.libtomcrypt.org 12 | */ 13 | #include 14 | 15 | int mpf_const_d(mp_float *a, long d) 16 | { 17 | long x, s; 18 | int err; 19 | 20 | if (d < 0) { 21 | x = -d; 22 | s = MP_NEG; 23 | } else { 24 | x = d; 25 | s = MP_ZPOS; 26 | } 27 | 28 | if ((err = mp_set_int(&(a->mantissa), x)) != MP_OKAY) { 29 | return err; 30 | } 31 | 32 | a->mantissa.sign = s; 33 | a->exp = 0; 34 | return mpf_normalize(a); 35 | } 36 | -------------------------------------------------------------------------------- /mpf_const_e.c: -------------------------------------------------------------------------------- 1 | /* LibTomFloat, multiple-precision floating-point library 2 | * 3 | * LibTomFloat is a library that provides multiple-precision 4 | * floating-point artihmetic as well as trigonometric functionality. 5 | * 6 | * This library requires the public domain LibTomMath to be installed. 7 | * 8 | * This library is free for all purposes without any express 9 | * gurantee it works 10 | * 11 | * Tom St Denis, tomstdenis@iahu.ca, http://float.libtomcrypt.org 12 | */ 13 | #include 14 | 15 | int mpf_const_e(mp_float *a) 16 | { 17 | int err; 18 | 19 | if ((err = mpf_const_d(a, 1)) != MP_OKAY) { 20 | return err; 21 | } 22 | return mpf_exp(a, a); 23 | } 24 | -------------------------------------------------------------------------------- /mpf_const_l10e.c: -------------------------------------------------------------------------------- 1 | /* LibTomFloat, multiple-precision floating-point library 2 | * 3 | * LibTomFloat is a library that provides multiple-precision 4 | * floating-point artihmetic as well as trigonometric functionality. 5 | * 6 | * This library requires the public domain LibTomMath to be installed. 7 | * 8 | * This library is free for all purposes without any express 9 | * gurantee it works 10 | * 11 | * Tom St Denis, tomstdenis@iahu.ca, http://float.libtomcrypt.org 12 | */ 13 | #include 14 | 15 | int mpf_const_l10e(mp_float *a) 16 | { 17 | int err; 18 | if ((err = mpf_const_ln_d(a, 10)) != MP_OKAY) { 19 | return err; 20 | } 21 | return mpf_inv(a, a); 22 | } 23 | /* log_10 e == 1/ln(e) */ 24 | 25 | -------------------------------------------------------------------------------- /mpf_const_l2e.c: -------------------------------------------------------------------------------- 1 | /* LibTomFloat, multiple-precision floating-point library 2 | * 3 | * LibTomFloat is a library that provides multiple-precision 4 | * floating-point artihmetic as well as trigonometric functionality. 5 | * 6 | * This library requires the public domain LibTomMath to be installed. 7 | * 8 | * This library is free for all purposes without any express 9 | * gurantee it works 10 | * 11 | * Tom St Denis, tomstdenis@iahu.ca, http://float.libtomcrypt.org 12 | */ 13 | #include 14 | 15 | int mpf_const_l2e(mp_float *a) 16 | { 17 | int err; 18 | if ((err = mpf_const_ln_d(a, 2)) != MP_OKAY) { 19 | return err; 20 | } 21 | return mpf_inv(a, a); 22 | } 23 | /* log_2 e a.k.a 1/ln2 */ 24 | 25 | -------------------------------------------------------------------------------- /mpf_const_le2.c: -------------------------------------------------------------------------------- 1 | /* LibTomFloat, multiple-precision floating-point library 2 | * 3 | * LibTomFloat is a library that provides multiple-precision 4 | * floating-point artihmetic as well as trigonometric functionality. 5 | * 6 | * This library requires the public domain LibTomMath to be installed. 7 | * 8 | * This library is free for all purposes without any express 9 | * gurantee it works 10 | * 11 | * Tom St Denis, tomstdenis@iahu.ca, http://float.libtomcrypt.org 12 | */ 13 | #include 14 | 15 | int mpf_const_le2(mp_float *a) 16 | { 17 | return mpf_const_ln_d(a, 2); 18 | } 19 | /* log_e 2 */ 20 | 21 | -------------------------------------------------------------------------------- /mpf_const_ln_d.c: -------------------------------------------------------------------------------- 1 | /* LibTomFloat, multiple-precision floating-point library 2 | * 3 | * LibTomFloat is a library that provides multiple-precision 4 | * floating-point artihmetic as well as trigonometric functionality. 5 | * 6 | * This library requires the public domain LibTomMath to be installed. 7 | * 8 | * This library is free for all purposes without any express 9 | * gurantee it works 10 | * 11 | * Tom St Denis, tomstdenis@iahu.ca, http://float.libtomcrypt.org 12 | */ 13 | #include 14 | 15 | int mpf_const_ln_d(mp_float *a, long b) 16 | { 17 | int err; 18 | 19 | /* test input */ 20 | if (b < 0) { 21 | return MP_VAL; 22 | } 23 | 24 | if (b == 0) { 25 | return mpf_const_d(a, 1); 26 | } 27 | 28 | if (b == 1) { 29 | return mpf_const_d(a, 0); 30 | } 31 | 32 | if ((err = mpf_const_d(a, b)) != MP_OKAY) { 33 | return err; 34 | } 35 | return mpf_ln(a, a); 36 | } 37 | /* a = ln b */ 38 | 39 | -------------------------------------------------------------------------------- /mpf_const_pi.c: -------------------------------------------------------------------------------- 1 | /* LibTomFloat, multiple-precision floating-point library 2 | * 3 | * LibTomFloat is a library that provides multiple-precision 4 | * floating-point artihmetic as well as trigonometric functionality. 5 | * 6 | * This library requires the public domain LibTomMath to be installed. 7 | * 8 | * This library is free for all purposes without any express 9 | * gurantee it works 10 | * 11 | * Tom St Denis, tomstdenis@iahu.ca, http://float.libtomcrypt.org 12 | */ 13 | #include 14 | 15 | 16 | /* Pi = 4arctan(1) */ 17 | int mpf_const_pi(mp_float *a) 18 | { 19 | int err; 20 | if ((err = mpf_const_d(a, 1)) != MP_OKAY) { 21 | return err; 22 | } 23 | if ((err = mpf_atan(a, a)) != MP_OKAY) { 24 | return err; 25 | } 26 | if ((err = mpf_mul_2(a, a)) != MP_OKAY) { 27 | return err; 28 | } 29 | return mpf_mul_2(a, a); 30 | } 31 | /* Pi */ 32 | 33 | -------------------------------------------------------------------------------- /mpf_const_pi2.c: -------------------------------------------------------------------------------- 1 | /* LibTomFloat, multiple-precision floating-point library 2 | * 3 | * LibTomFloat is a library that provides multiple-precision 4 | * floating-point artihmetic as well as trigonometric functionality. 5 | * 6 | * This library requires the public domain LibTomMath to be installed. 7 | * 8 | * This library is free for all purposes without any express 9 | * gurantee it works 10 | * 11 | * Tom St Denis, tomstdenis@iahu.ca, http://float.libtomcrypt.org 12 | */ 13 | #include 14 | 15 | int mpf_const_pi2(mp_float *a) 16 | { 17 | int err; 18 | if ((err = mpf_const_pi(a)) != MP_OKAY) { 19 | return err; 20 | } 21 | return mpf_div_2(a, a); 22 | } 23 | /* Pi/2 */ 24 | 25 | -------------------------------------------------------------------------------- /mpf_const_pi4.c: -------------------------------------------------------------------------------- 1 | /* LibTomFloat, multiple-precision floating-point library 2 | * 3 | * LibTomFloat is a library that provides multiple-precision 4 | * floating-point artihmetic as well as trigonometric functionality. 5 | * 6 | * This library requires the public domain LibTomMath to be installed. 7 | * 8 | * This library is free for all purposes without any express 9 | * gurantee it works 10 | * 11 | * Tom St Denis, tomstdenis@iahu.ca, http://float.libtomcrypt.org 12 | */ 13 | #include 14 | 15 | int mpf_const_pi4(mp_float *a) 16 | { 17 | int err; 18 | if ((err = mpf_const_pi(a)) != MP_OKAY) { 19 | return err; 20 | } 21 | if ((err = mpf_div_2(a, a)) != MP_OKAY) { 22 | return err; 23 | } 24 | return mpf_div_2(a, a); 25 | } 26 | /* Pi/4 */ 27 | 28 | -------------------------------------------------------------------------------- /mpf_const_r2.c: -------------------------------------------------------------------------------- 1 | /* LibTomFloat, multiple-precision floating-point library 2 | * 3 | * LibTomFloat is a library that provides multiple-precision 4 | * floating-point artihmetic as well as trigonometric functionality. 5 | * 6 | * This library requires the public domain LibTomMath to be installed. 7 | * 8 | * This library is free for all purposes without any express 9 | * gurantee it works 10 | * 11 | * Tom St Denis, tomstdenis@iahu.ca, http://float.libtomcrypt.org 12 | */ 13 | #include 14 | 15 | int mpf_const_r2(mp_float *a) 16 | { 17 | return mpf_const_sqrt_d(a, 2); 18 | } 19 | /* sqrt(2) */ 20 | 21 | -------------------------------------------------------------------------------- /mpf_const_sqrt_d.c: -------------------------------------------------------------------------------- 1 | /* LibTomFloat, multiple-precision floating-point library 2 | * 3 | * LibTomFloat is a library that provides multiple-precision 4 | * floating-point artihmetic as well as trigonometric functionality. 5 | * 6 | * This library requires the public domain LibTomMath to be installed. 7 | * 8 | * This library is free for all purposes without any express 9 | * gurantee it works 10 | * 11 | * Tom St Denis, tomstdenis@iahu.ca, http://float.libtomcrypt.org 12 | */ 13 | #include 14 | 15 | int mpf_const_sqrt_d(mp_float *a, long b) 16 | { 17 | int err; 18 | if ((err = mpf_const_d(a, b)) != MP_OKAY) { 19 | return err; 20 | } 21 | return mpf_sqrt(a, a); 22 | } 23 | -------------------------------------------------------------------------------- /mpf_copy.c: -------------------------------------------------------------------------------- 1 | /* LibTomFloat, multiple-precision floating-point library 2 | * 3 | * LibTomFloat is a library that provides multiple-precision 4 | * floating-point artihmetic as well as trigonometric functionality. 5 | * 6 | * This library requires the public domain LibTomMath to be installed. 7 | * 8 | * This library is free for all purposes without any express 9 | * gurantee it works 10 | * 11 | * Tom St Denis, tomstdenis@iahu.ca, http://float.libtomcrypt.org 12 | */ 13 | #include 14 | 15 | int mpf_copy(mp_float *src, mp_float *dest) 16 | { 17 | if (src == dest) { 18 | return MP_OKAY; 19 | } 20 | dest->radix = src->radix; 21 | dest->exp = src->exp; 22 | return mp_copy(&(src->mantissa), &(dest->mantissa)); 23 | } 24 | -------------------------------------------------------------------------------- /mpf_cos.c: -------------------------------------------------------------------------------- 1 | /* LibTomFloat, multiple-precision floating-point library 2 | * 3 | * LibTomFloat is a library that provides multiple-precision 4 | * floating-point artihmetic as well as trigonometric functionality. 5 | * 6 | * This library requires the public domain LibTomMath to be installed. 7 | * 8 | * This library is free for all purposes without any express 9 | * gurantee it works 10 | * 11 | * Tom St Denis, tomstdenis@iahu.ca, http://float.libtomcrypt.org 12 | */ 13 | #include 14 | 15 | /* using cos x == \sum_{n=0}^{\infty} ((-1)^n/(2n)!) * x^2n */ 16 | int mpf_cos(mp_float *a, mp_float *b) 17 | { 18 | mp_float oldval, tmpovern, tmp, tmpx, res, sqr; 19 | int oddeven, err, itts; 20 | long n; 21 | /* initialize temps */ 22 | if ((err = mpf_init_multi(b->radix, &oldval, &tmpx, &tmpovern, &tmp, &res, &sqr, NULL)) != MP_OKAY) { 23 | return err; 24 | } 25 | 26 | /* initlialize temps */ 27 | /* three start at one, sqr is the square of a */ 28 | if ((err = mpf_const_d(&res, 1)) != MP_OKAY) { goto __ERR; } 29 | if ((err = mpf_const_d(&tmpovern, 1)) != MP_OKAY) { goto __ERR; } 30 | if ((err = mpf_const_d(&tmpx, 1)) != MP_OKAY) { goto __ERR; } 31 | if ((err = mpf_sqr(a, &sqr)) != MP_OKAY) { goto __ERR; } 32 | 33 | /* this is the denom counter. Goes up by two per pass */ 34 | n = 0; 35 | 36 | /* we alternate between adding and subtracting */ 37 | oddeven = 1; 38 | 39 | /* get number of iterations */ 40 | itts = mpf_iterations(b); 41 | 42 | while (itts-- > 0) { 43 | if ((err = mpf_copy(&res, &oldval)) != MP_OKAY) { goto __ERR; } 44 | /* compute 1/(2n)! from 1/(2(n-1))! by multiplying by (1/n)(1/(n+1)) */ 45 | if ((err = mpf_const_d(&tmp, ++n)) != MP_OKAY) { goto __ERR; } 46 | if ((err = mpf_inv(&tmp, &tmp)) != MP_OKAY) { goto __ERR; } 47 | if ((err = mpf_mul(&tmpovern, &tmp, &tmpovern)) != MP_OKAY) { goto __ERR; } 48 | /* we do this twice */ 49 | if ((err = mpf_const_d(&tmp, ++n)) != MP_OKAY) { goto __ERR; } 50 | if ((err = mpf_inv(&tmp, &tmp)) != MP_OKAY) { goto __ERR; } 51 | if ((err = mpf_mul(&tmpovern, &tmp, &tmpovern)) != MP_OKAY) { goto __ERR; } 52 | 53 | /* now multiply a into tmpx twice */ 54 | if ((err = mpf_mul(&tmpx, &sqr, &tmpx)) != MP_OKAY) { goto __ERR; } 55 | 56 | /* now multiply the two */ 57 | if ((err = mpf_mul(&tmpx, &tmpovern, &tmp)) != MP_OKAY) { goto __ERR; } 58 | 59 | /* now depending on if this is even or odd we add/sub */ 60 | oddeven ^= 1; 61 | if (oddeven == 1) { 62 | if ((err = mpf_add(&res, &tmp, &res)) != MP_OKAY) { goto __ERR; } 63 | } else { 64 | if ((err = mpf_sub(&res, &tmp, &res)) != MP_OKAY) { goto __ERR; } 65 | } 66 | 67 | if (mpf_cmp(&res, &oldval) == MP_EQ) { 68 | break; 69 | } 70 | } 71 | mpf_exch(&res, b); 72 | __ERR: mpf_clear_multi(&oldval, &tmpx, &tmpovern, &tmp, &res, &sqr, NULL); 73 | return err; 74 | } 75 | -------------------------------------------------------------------------------- /mpf_div.c: -------------------------------------------------------------------------------- 1 | /* LibTomFloat, multiple-precision floating-point library 2 | * 3 | * LibTomFloat is a library that provides multiple-precision 4 | * floating-point artihmetic as well as trigonometric functionality. 5 | * 6 | * This library requires the public domain LibTomMath to be installed. 7 | * 8 | * This library is free for all purposes without any express 9 | * gurantee it works 10 | * 11 | * Tom St Denis, tomstdenis@iahu.ca, http://float.libtomcrypt.org 12 | */ 13 | #include 14 | 15 | int mpf_div(mp_float *a, mp_float *b, mp_float *c) 16 | { 17 | mp_float tmp; 18 | int err; 19 | 20 | /* ensure b is not zero */ 21 | if (mp_iszero(&(b->mantissa)) == MP_YES) { 22 | return MP_VAL; 23 | } 24 | 25 | /* find 1/b */ 26 | if ((err = mpf_init(&tmp, c->radix)) != MP_OKAY) { 27 | return err; 28 | } 29 | if ((err = mpf_inv(b, &tmp)) != MP_OKAY) { goto __ERR; } 30 | 31 | /* now multiply */ 32 | err = mpf_mul(&tmp, a, c); 33 | 34 | __ERR: mpf_clear(&tmp); 35 | return err; 36 | } 37 | 38 | -------------------------------------------------------------------------------- /mpf_div_2.c: -------------------------------------------------------------------------------- 1 | /* LibTomFloat, multiple-precision floating-point library 2 | * 3 | * LibTomFloat is a library that provides multiple-precision 4 | * floating-point artihmetic as well as trigonometric functionality. 5 | * 6 | * This library requires the public domain LibTomMath to be installed. 7 | * 8 | * This library is free for all purposes without any express 9 | * gurantee it works 10 | * 11 | * Tom St Denis, tomstdenis@iahu.ca, http://float.libtomcrypt.org 12 | */ 13 | #include 14 | 15 | int mpf_div_2(mp_float *a, mp_float *b) 16 | { 17 | int err; 18 | 19 | /* |b| = |a|/2 */ 20 | if ((err = mp_copy(&(a->mantissa), &(b->mantissa))) != MP_OKAY) { 21 | return err; 22 | } 23 | b->exp = a->exp - 1; 24 | return mpf_normalize(b); 25 | } 26 | -------------------------------------------------------------------------------- /mpf_div_d.c: -------------------------------------------------------------------------------- 1 | /* LibTomFloat, multiple-precision floating-point library 2 | * 3 | * LibTomFloat is a library that provides multiple-precision 4 | * floating-point artihmetic as well as trigonometric functionality. 5 | * 6 | * This library requires the public domain LibTomMath to be installed. 7 | * 8 | * This library is free for all purposes without any express 9 | * gurantee it works 10 | * 11 | * Tom St Denis, tomstdenis@iahu.ca, http://float.libtomcrypt.org 12 | */ 13 | #include 14 | 15 | int mpf_div_d(mp_float *a, long b, mp_float *c) 16 | { 17 | int err; 18 | mp_float tmp; 19 | 20 | if ((err = mpf_init(&tmp, c->radix)) != MP_OKAY) { 21 | return err; 22 | } 23 | 24 | if ((err = mpf_const_d(&tmp, b)) != MP_OKAY) { goto __ERR; } 25 | err = mpf_div(a, &tmp, c); 26 | 27 | __ERR: 28 | mpf_clear(&tmp); 29 | return err; 30 | } 31 | 32 | -------------------------------------------------------------------------------- /mpf_exch.c: -------------------------------------------------------------------------------- 1 | /* LibTomFloat, multiple-precision floating-point library 2 | * 3 | * LibTomFloat is a library that provides multiple-precision 4 | * floating-point artihmetic as well as trigonometric functionality. 5 | * 6 | * This library requires the public domain LibTomMath to be installed. 7 | * 8 | * This library is free for all purposes without any express 9 | * gurantee it works 10 | * 11 | * Tom St Denis, tomstdenis@iahu.ca, http://float.libtomcrypt.org 12 | */ 13 | #include 14 | 15 | void mpf_exch(mp_float *a, mp_float *b) 16 | { 17 | mp_float tmp; 18 | tmp = *a; *a = *b; *b = tmp; 19 | } 20 | 21 | -------------------------------------------------------------------------------- /mpf_exp.c: -------------------------------------------------------------------------------- 1 | /* LibTomFloat, multiple-precision floating-point library 2 | * 3 | * LibTomFloat is a library that provides multiple-precision 4 | * floating-point artihmetic as well as trigonometric functionality. 5 | * 6 | * This library requires the public domain LibTomMath to be installed. 7 | * 8 | * This library is free for all purposes without any express 9 | * gurantee it works 10 | * 11 | * Tom St Denis, tomstdenis@iahu.ca, http://float.libtomcrypt.org 12 | */ 13 | #include 14 | 15 | 16 | /* compute b = e^a using e^x == \sum_{n=0}^{\infty} {1 \over n!}x^n */ 17 | int mpf_exp(mp_float *a, mp_float *b) 18 | { 19 | mp_float oldval, tmpx, tmpovern, tmp, res; 20 | int err, itts; 21 | long n; 22 | 23 | /* initialize temps */ 24 | if ((err = mpf_init_multi(b->radix, &oldval, &tmpx, &tmpovern, &tmp, &res, NULL)) != MP_OKAY) { 25 | return err; 26 | } 27 | 28 | /* initlialize temps */ 29 | /* all three start at one */ 30 | if ((err = mpf_const_d(&res, 1)) != MP_OKAY) { goto __ERR; } 31 | if ((err = mpf_const_d(&tmpovern, 1)) != MP_OKAY) { goto __ERR; } 32 | if ((err = mpf_const_d(&tmpx, 1)) != MP_OKAY) { goto __ERR; } 33 | n = 1; 34 | 35 | /* get number of iterations */ 36 | itts = mpf_iterations(b); 37 | 38 | while (itts-- > 0) { 39 | if ((err = mpf_copy(&res, &oldval)) != MP_OKAY) { goto __ERR; } 40 | 41 | /* compute 1/n! as 1/(n-1)! * 1/n */ 42 | if ((err = mpf_const_d(&tmp, n++)) != MP_OKAY) { goto __ERR; } 43 | if ((err = mpf_inv(&tmp, &tmp)) != MP_OKAY) { goto __ERR; } 44 | if ((err = mpf_mul(&tmp, &tmpovern, &tmpovern)) != MP_OKAY) { goto __ERR; } 45 | 46 | /* compute x^n as x^(n-1) * x */ 47 | if ((err = mpf_mul(&tmpx, a, &tmpx)) != MP_OKAY) { goto __ERR; } 48 | 49 | /* multiply and sum them */ 50 | if ((err = mpf_mul(&tmpovern, &tmpx, &tmp)) != MP_OKAY) { goto __ERR; } 51 | if ((err = mpf_add(&tmp, &res, &res)) != MP_OKAY) { goto __ERR; } 52 | 53 | if (mpf_cmp(&oldval, &res) == MP_EQ) { 54 | break; 55 | } 56 | } 57 | 58 | mpf_exch(&res, b); 59 | __ERR: mpf_clear_multi(&oldval, &tmpx, &tmpovern, &tmp, &res, NULL); 60 | return err; 61 | } 62 | 63 | -------------------------------------------------------------------------------- /mpf_init.c: -------------------------------------------------------------------------------- 1 | /* LibTomFloat, multiple-precision floating-point library 2 | * 3 | * LibTomFloat is a library that provides multiple-precision 4 | * floating-point artihmetic as well as trigonometric functionality. 5 | * 6 | * This library requires the public domain LibTomMath to be installed. 7 | * 8 | * This library is free for all purposes without any express 9 | * gurantee it works 10 | * 11 | * Tom St Denis, tomstdenis@iahu.ca, http://float.libtomcrypt.org 12 | */ 13 | #include 14 | 15 | int mpf_init(mp_float *a, long radix) 16 | { 17 | a->radix = radix; 18 | a->exp = 1; 19 | return mp_init(&(a->mantissa)); 20 | } 21 | -------------------------------------------------------------------------------- /mpf_init_copy.c: -------------------------------------------------------------------------------- 1 | /* LibTomFloat, multiple-precision floating-point library 2 | * 3 | * LibTomFloat is a library that provides multiple-precision 4 | * floating-point artihmetic as well as trigonometric functionality. 5 | * 6 | * This library requires the public domain LibTomMath to be installed. 7 | * 8 | * This library is free for all purposes without any express 9 | * gurantee it works 10 | * 11 | * Tom St Denis, tomstdenis@iahu.ca, http://float.libtomcrypt.org 12 | */ 13 | #include 14 | 15 | int mpf_init_copy(mp_float *a, mp_float *b) 16 | { 17 | int err; 18 | if ((err = mpf_init(b, a->radix)) != MP_OKAY) { 19 | return err; 20 | } 21 | return mpf_copy(a, b); 22 | } 23 | 24 | -------------------------------------------------------------------------------- /mpf_init_multi.c: -------------------------------------------------------------------------------- 1 | /* LibTomFloat, multiple-precision floating-point library 2 | * 3 | * LibTomFloat is a library that provides multiple-precision 4 | * floating-point artihmetic as well as trigonometric functionality. 5 | * 6 | * This library requires the public domain LibTomMath to be installed. 7 | * 8 | * This library is free for all purposes without any express 9 | * gurantee it works 10 | * 11 | * Tom St Denis, tomstdenis@iahu.ca, http://float.libtomcrypt.org 12 | */ 13 | #include 14 | #include 15 | 16 | int mpf_init_multi(long radix, mp_float *a, ...) 17 | { 18 | mp_err res = MP_OKAY; /* Assume ok until proven otherwise */ 19 | int n = 0; /* Number of ok inits */ 20 | mp_float* cur_arg = a; 21 | va_list args; 22 | 23 | va_start(args, a); /* init args to next argument from caller */ 24 | while (cur_arg != NULL) { 25 | if (mpf_init(cur_arg, radix) != MP_OKAY) { 26 | /* Oops - error! Back-track and mp_clear what we already 27 | succeeded in init-ing, then return error. 28 | */ 29 | va_list clean_args; 30 | 31 | /* end the current list */ 32 | va_end(args); 33 | 34 | /* now start cleaning up */ 35 | cur_arg = a; 36 | va_start(clean_args, a); 37 | while (n--) { 38 | mpf_clear(cur_arg); 39 | cur_arg = va_arg(clean_args, mp_float*); 40 | } 41 | va_end(clean_args); 42 | res = MP_MEM; 43 | break; 44 | } 45 | n++; 46 | cur_arg = va_arg(args, mp_float*); 47 | } 48 | va_end(args); 49 | return res; /* Assumed ok, if error flagged above. */ 50 | } 51 | -------------------------------------------------------------------------------- /mpf_inv.c: -------------------------------------------------------------------------------- 1 | /* LibTomFloat, multiple-precision floating-point library 2 | * 3 | * LibTomFloat is a library that provides multiple-precision 4 | * floating-point artihmetic as well as trigonometric functionality. 5 | * 6 | * This library requires the public domain LibTomMath to be installed. 7 | * 8 | * This library is free for all purposes without any express 9 | * gurantee it works 10 | * 11 | * Tom St Denis, tomstdenis@iahu.ca, http://float.libtomcrypt.org 12 | */ 13 | #include 14 | 15 | /* compute 1/x by (1/sqrt(x))^2 */ 16 | int mpf_inv(mp_float *a, mp_float *b) 17 | { 18 | int err, sign; 19 | 20 | /* get sign of input */ 21 | sign = a->mantissa.sign; 22 | 23 | /* force to positive */ 24 | a->mantissa.sign = MP_ZPOS; 25 | 26 | /* compute 1/sqrt(a) */ 27 | if ((err = mpf_invsqrt(a, b)) != MP_OKAY) { 28 | return err; 29 | } 30 | 31 | /* square 1/sqrt(a) to get 1/a */ 32 | err = mpf_sqr(b, b); 33 | 34 | /* now restore the sign */ 35 | b->mantissa.sign = a->mantissa.sign = sign; 36 | 37 | return err; 38 | } 39 | 40 | -------------------------------------------------------------------------------- /mpf_invsqrt.c: -------------------------------------------------------------------------------- 1 | /* LibTomFloat, multiple-precision floating-point library 2 | * 3 | * LibTomFloat is a library that provides multiple-precision 4 | * floating-point artihmetic as well as trigonometric functionality. 5 | * 6 | * This library requires the public domain LibTomMath to be installed. 7 | * 8 | * This library is free for all purposes without any express 9 | * gurantee it works 10 | * 11 | * Tom St Denis, tomstdenis@iahu.ca, http://float.libtomcrypt.org 12 | */ 13 | #include 14 | 15 | /* using newtons method we have 1/sqrt(x) = Y_{n+1} = y_n * ((3 - xy^2_n)/2) */ 16 | int mpf_invsqrt(mp_float *a, mp_float *b) 17 | { 18 | mp_float oldval, tmp1, tmp2, const_3; 19 | int err, itts; 20 | 21 | /* ensure a is not zero or negative */ 22 | if ((mp_iszero(&(a->mantissa)) == MP_YES) || (a->mantissa.sign == MP_NEG)) { 23 | return MP_VAL; 24 | } 25 | 26 | /* get number of iterations */ 27 | itts = mpf_iterations(b); 28 | 29 | /* init temps */ 30 | if ((err = mpf_init_multi(b->radix, &oldval, &tmp1, &tmp2, &const_3, NULL)) != MP_OKAY) { 31 | return err; 32 | } 33 | 34 | /* const_3 */ 35 | if ((err = mpf_const_d(&const_3, 3)) != MP_OKAY) { goto __ERR; } 36 | 37 | /* tmp1 == reasonable guess at sqrt */ 38 | if ((err = mpf_copy(a, &tmp1)) != MP_OKAY) { goto __ERR; } 39 | mp_rshd(&(tmp1.mantissa), tmp1.mantissa.used>>1); 40 | if ((err = mpf_normalize_to(&tmp1, b->radix)) != MP_OKAY) { goto __ERR; } 41 | 42 | while (itts-- > 0) { 43 | /* grap copy of tmp1 for early out */ 44 | if ((err = mpf_copy(&tmp1, &oldval)) != MP_OKAY) { goto __ERR; } 45 | 46 | /* first tmp2 = y^2 == tmp1^2 */ 47 | if ((err = mpf_sqr(&tmp1, &tmp2)) != MP_OKAY) { goto __ERR; } 48 | /* multiply by x, tmp1 * a */ 49 | if ((err = mpf_mul(&tmp2, a, &tmp2)) != MP_OKAY) { goto __ERR; } 50 | /* 3 - xy^2_n == 3 - tmp1 */ 51 | if ((err = mpf_sub(&const_3, &tmp2, &tmp2)) != MP_OKAY) { goto __ERR; } 52 | /* halve it */ 53 | if ((err = mpf_div_2(&tmp2, &tmp2)) != MP_OKAY) { goto __ERR; } 54 | /* multiply by y_n and feedback */ 55 | if ((err = mpf_mul(&tmp1, &tmp2, &tmp1)) != MP_OKAY) { goto __ERR; } 56 | 57 | /* early out if stable */ 58 | if (mpf_cmp(&oldval, &tmp1) == MP_EQ) { 59 | break; 60 | } 61 | } 62 | 63 | mpf_exch(&tmp1, b); 64 | __ERR: mpf_clear_multi(&oldval, &tmp1, &tmp2, &const_3, NULL); 65 | return err; 66 | } 67 | 68 | -------------------------------------------------------------------------------- /mpf_iterations.c: -------------------------------------------------------------------------------- 1 | /* LibTomFloat, multiple-precision floating-point library 2 | * 3 | * LibTomFloat is a library that provides multiple-precision 4 | * floating-point artihmetic as well as trigonometric functionality. 5 | * 6 | * This library requires the public domain LibTomMath to be installed. 7 | * 8 | * This library is free for all purposes without any express 9 | * gurantee it works 10 | * 11 | * Tom St Denis, tomstdenis@iahu.ca, http://float.libtomcrypt.org 12 | */ 13 | #include 14 | 15 | int mpf_iterations(mp_float *a) 16 | { 17 | int itts; 18 | 19 | /* always perform at least eight iterations */ 20 | itts = 8; 21 | 22 | /* now add roughly radix */ 23 | itts += a->radix; 24 | 25 | return itts; 26 | } 27 | -------------------------------------------------------------------------------- /mpf_ln.c: -------------------------------------------------------------------------------- 1 | /* LibTomFloat, multiple-precision floating-point library 2 | * 3 | * LibTomFloat is a library that provides multiple-precision 4 | * floating-point artihmetic as well as trigonometric functionality. 5 | * 6 | * This library requires the public domain LibTomMath to be installed. 7 | * 8 | * This library is free for all purposes without any express 9 | * gurantee it works 10 | * 11 | * Tom St Denis, tomstdenis@iahu.ca, http://float.libtomcrypt.org 12 | */ 13 | #include 14 | 15 | /* 16 | 17 | Using the newton approximation y1 = y - (e^y - x)/e^y 18 | 19 | Which converges quickly and we can reuse e^y so we only calc it once per loop 20 | 21 | */ 22 | int mpf_ln(mp_float *a, mp_float *b) 23 | { 24 | mp_float oldval, tmpey, tmpy, val; 25 | int itts, err; 26 | long k; 27 | 28 | /* ensure positive */ 29 | if (a->mantissa.sign == MP_NEG) { 30 | return MP_VAL; 31 | } 32 | 33 | /* easy out for 0 */ 34 | if (mpf_iszero(a) == MP_YES) { 35 | return mpf_const_d(b, 1); 36 | } 37 | 38 | /* initialize temps */ 39 | if ((err = mpf_init_multi(b->radix, &oldval, &tmpey, &tmpy, &val, NULL)) != MP_OKAY) { 40 | return err; 41 | } 42 | 43 | /* initial guess */ 44 | if ((err = mpf_const_e(&val)) != MP_OKAY) { goto __ERR; } 45 | if ((err = mpf_sqr(&val, &val)) != MP_OKAY) { goto __ERR; } 46 | if ((err = mpf_inv(&val, &tmpey)) != MP_OKAY) { goto __ERR; } 47 | if ((err = mpf_copy(a, &tmpy)) != MP_OKAY) { goto __ERR; } 48 | if ((err = mpf_normalize_to(&tmpy, b->radix)) != MP_OKAY) { goto __ERR; } 49 | 50 | /* divide out e's */ 51 | k = 0; 52 | while (mpf_cmp(&tmpy, &val) == MP_GT) { 53 | ++k; 54 | if ((err = mpf_mul(&tmpy, &tmpey, &tmpy)) != MP_OKAY) { goto __ERR; } 55 | } 56 | if ((err = mpf_const_d(&tmpy, k*2)) != MP_OKAY) { goto __ERR; } 57 | 58 | /* number of iterations */ 59 | itts = mpf_iterations(b); 60 | 61 | while (itts--) { 62 | if ((err = mpf_copy(&tmpy, &oldval)) != MP_OKAY) { goto __ERR; } 63 | 64 | /* get e^y and save it */ 65 | if ((err = mpf_exp(&tmpy, &tmpey)) != MP_OKAY) { goto __ERR; } 66 | 67 | /* now compute e^y - x */ 68 | if ((err = mpf_sub(&tmpey, a, &val)) != MP_OKAY) { goto __ERR; } 69 | 70 | /* now compute (e^y - x) / e^y */ 71 | if ((err = mpf_div(&val, &tmpey, &val)) != MP_OKAY) { goto __ERR; } 72 | 73 | /* y = y - (e^y - x)/e^y */ 74 | if ((err = mpf_sub(&tmpy, &val, &tmpy)) != MP_OKAY) { goto __ERR; } 75 | 76 | if (mpf_cmp(&tmpy, &oldval) == MP_EQ) { 77 | break; 78 | } 79 | } 80 | mpf_exch(&tmpy, b); 81 | __ERR: mpf_clear_multi(&oldval, &tmpey, &tmpy, &val, NULL); 82 | return err; 83 | } 84 | -------------------------------------------------------------------------------- /mpf_mul.c: -------------------------------------------------------------------------------- 1 | /* LibTomFloat, multiple-precision floating-point library 2 | * 3 | * LibTomFloat is a library that provides multiple-precision 4 | * floating-point artihmetic as well as trigonometric functionality. 5 | * 6 | * This library requires the public domain LibTomMath to be installed. 7 | * 8 | * This library is free for all purposes without any express 9 | * gurantee it works 10 | * 11 | * Tom St Denis, tomstdenis@iahu.ca, http://float.libtomcrypt.org 12 | */ 13 | #include 14 | 15 | int mpf_mul(mp_float *a, mp_float *b, mp_float *c) 16 | { 17 | int err; 18 | 19 | if ((err = mp_mul(&(a->mantissa), &(b->mantissa), &(c->mantissa))) != MP_OKAY) { 20 | return err; 21 | } 22 | c->exp = a->exp + b->exp; 23 | return mpf_normalize(c); 24 | } 25 | -------------------------------------------------------------------------------- /mpf_mul_2.c: -------------------------------------------------------------------------------- 1 | /* LibTomFloat, multiple-precision floating-point library 2 | * 3 | * LibTomFloat is a library that provides multiple-precision 4 | * floating-point artihmetic as well as trigonometric functionality. 5 | * 6 | * This library requires the public domain LibTomMath to be installed. 7 | * 8 | * This library is free for all purposes without any express 9 | * gurantee it works 10 | * 11 | * Tom St Denis, tomstdenis@iahu.ca, http://float.libtomcrypt.org 12 | */ 13 | #include 14 | 15 | int mpf_mul_2(mp_float *a, mp_float *b) 16 | { 17 | int err; 18 | 19 | /* |b| = 2|a| */ 20 | if ((err = mp_mul_2(&(a->mantissa), &(b->mantissa))) != MP_OKAY) { 21 | return err; 22 | } 23 | 24 | return mpf_normalize(b); 25 | } 26 | -------------------------------------------------------------------------------- /mpf_mul_d.c: -------------------------------------------------------------------------------- 1 | /* LibTomFloat, multiple-precision floating-point library 2 | * 3 | * LibTomFloat is a library that provides multiple-precision 4 | * floating-point artihmetic as well as trigonometric functionality. 5 | * 6 | * This library requires the public domain LibTomMath to be installed. 7 | * 8 | * This library is free for all purposes without any express 9 | * gurantee it works 10 | * 11 | * Tom St Denis, tomstdenis@iahu.ca, http://float.libtomcrypt.org 12 | */ 13 | #include 14 | 15 | int mpf_mul_d(mp_float *a, long b, mp_float *c) 16 | { 17 | int err; 18 | mp_float tmp; 19 | 20 | if ((err = mpf_init(&tmp, c->radix)) != MP_OKAY) { 21 | return err; 22 | } 23 | 24 | if ((err = mpf_const_d(&tmp, b)) != MP_OKAY) { goto __ERR; } 25 | err = mpf_mul(a, &tmp, c); 26 | 27 | __ERR: 28 | mpf_clear(&tmp); 29 | return err; 30 | } 31 | 32 | -------------------------------------------------------------------------------- /mpf_neg.c: -------------------------------------------------------------------------------- 1 | /* LibTomFloat, multiple-precision floating-point library 2 | * 3 | * LibTomFloat is a library that provides multiple-precision 4 | * floating-point artihmetic as well as trigonometric functionality. 5 | * 6 | * This library requires the public domain LibTomMath to be installed. 7 | * 8 | * This library is free for all purposes without any express 9 | * gurantee it works 10 | * 11 | * Tom St Denis, tomstdenis@iahu.ca, http://float.libtomcrypt.org 12 | */ 13 | #include 14 | 15 | int mpf_neg(mp_float *a, mp_float *b) 16 | { 17 | int err; 18 | if ((err = mp_neg((&a->mantissa), &(b->mantissa))) != MP_OKAY) { 19 | return err; 20 | } 21 | b->exp = a->exp; 22 | return mpf_normalize(b); 23 | } 24 | -------------------------------------------------------------------------------- /mpf_normalize.c: -------------------------------------------------------------------------------- 1 | /* LibTomFloat, multiple-precision floating-point library 2 | * 3 | * LibTomFloat is a library that provides multiple-precision 4 | * floating-point artihmetic as well as trigonometric functionality. 5 | * 6 | * This library requires the public domain LibTomMath to be installed. 7 | * 8 | * This library is free for all purposes without any express 9 | * gurantee it works 10 | * 11 | * Tom St Denis, tomstdenis@iahu.ca, http://float.libtomcrypt.org 12 | */ 13 | #include 14 | 15 | int mpf_normalize(mp_float *a) 16 | { 17 | long cb, diff; 18 | int err; 19 | mp_digit c; 20 | 21 | /* sanity */ 22 | if (a->radix < 2) { 23 | return MP_VAL; 24 | } 25 | 26 | cb = mp_count_bits(&(a->mantissa)); 27 | if (cb > a->radix) { 28 | diff = cb - a->radix; 29 | a->exp += diff; 30 | 31 | /* round it, add 1 after shift if diff-1'th bit is 1 */ 32 | c = a->mantissa.dp[diff/DIGIT_BIT] & (1U<<(diff%DIGIT_BIT)); 33 | if ((err = mp_div_2d(&(a->mantissa), diff, &(a->mantissa), NULL)) != MP_OKAY) { 34 | return err; 35 | } 36 | 37 | if (c != 0) { 38 | return mp_add_d(&(a->mantissa), 1, &(a->mantissa)); 39 | } else { 40 | return MP_OKAY; 41 | } 42 | } else if (cb < a->radix) { 43 | if (mp_iszero(&(a->mantissa)) == MP_YES) { 44 | return mpf_const_0(a); 45 | } else { 46 | diff = a->radix - cb; 47 | a->exp -= diff; 48 | return mp_mul_2d(&(a->mantissa), diff, &(a->mantissa)); 49 | } 50 | } 51 | return MP_OKAY; 52 | } 53 | 54 | -------------------------------------------------------------------------------- /mpf_normalize_to.c: -------------------------------------------------------------------------------- 1 | /* LibTomFloat, multiple-precision floating-point library 2 | * 3 | * LibTomFloat is a library that provides multiple-precision 4 | * floating-point artihmetic as well as trigonometric functionality. 5 | * 6 | * This library requires the public domain LibTomMath to be installed. 7 | * 8 | * This library is free for all purposes without any express 9 | * gurantee it works 10 | * 11 | * Tom St Denis, tomstdenis@iahu.ca, http://float.libtomcrypt.org 12 | */ 13 | #include 14 | 15 | int mpf_normalize_to(mp_float *a, long radix) 16 | { 17 | a->radix = radix; 18 | return mpf_normalize(a); 19 | } 20 | -------------------------------------------------------------------------------- /mpf_pow.c: -------------------------------------------------------------------------------- 1 | /* LibTomFloat, multiple-precision floating-point library 2 | * 3 | * LibTomFloat is a library that provides multiple-precision 4 | * floating-point artihmetic as well as trigonometric functionality. 5 | * 6 | * This library requires the public domain LibTomMath to be installed. 7 | * 8 | * This library is free for all purposes without any express 9 | * gurantee it works 10 | * 11 | * Tom St Denis, tomstdenis@iahu.ca, http://float.libtomcrypt.org 12 | */ 13 | #include 14 | 15 | /* we have e^x, so why not write a^b as e^(lna * b) ;-) w00t w00t */ 16 | int mpf_pow(mp_float *a, mp_float *b, mp_float *c) 17 | { 18 | mp_float exponent; 19 | int err; 20 | 21 | if ((err = mpf_init(&exponent, c->radix)) != MP_OKAY) { 22 | return err; 23 | } 24 | 25 | /* get ln of a */ 26 | if ((err = mpf_ln(a, &exponent)) != MP_OKAY) { goto __ERR; } 27 | 28 | /* multiply it by b */ 29 | if ((err = mpf_mul(&exponent, b, &exponent)) != MP_OKAY) { goto __ERR; } 30 | 31 | /* now evaluate it */ 32 | err = mpf_exp(&exponent, c); 33 | 34 | __ERR: mpf_clear(&exponent); 35 | return err; 36 | } 37 | -------------------------------------------------------------------------------- /mpf_sin.c: -------------------------------------------------------------------------------- 1 | /* LibTomFloat, multiple-precision floating-point library 2 | * 3 | * LibTomFloat is a library that provides multiple-precision 4 | * floating-point artihmetic as well as trigonometric functionality. 5 | * 6 | * This library requires the public domain LibTomMath to be installed. 7 | * 8 | * This library is free for all purposes without any express 9 | * gurantee it works 10 | * 11 | * Tom St Denis, tomstdenis@iahu.ca, http://float.libtomcrypt.org 12 | */ 13 | #include 14 | 15 | /* using sin x == \sum_{n=0}^{\infty} ((-1)^n/(2n+1)!) * x^(2n+1) */ 16 | int mpf_sin(mp_float *a, mp_float *b) 17 | { 18 | mp_float oldval, tmpovern, tmp, tmpx, res, sqr; 19 | int oddeven, err, itts; 20 | long n; 21 | 22 | /* initialize temps */ 23 | if ((err = mpf_init_multi(b->radix, &oldval, &tmpx, &tmpovern, &tmp, &res, &sqr, NULL)) != MP_OKAY) { 24 | return err; 25 | } 26 | 27 | /* initlialize temps */ 28 | /* this is the 1/n! which starts at 1 */ 29 | if ((err = mpf_const_d(&tmpovern, 1)) != MP_OKAY) { goto __ERR; } 30 | 31 | /* the square of the input, used to save multiplications later */ 32 | if ((err = mpf_sqr(a, &sqr)) != MP_OKAY) { goto __ERR; } 33 | 34 | /* tmpx starts at the input, so we copy and normalize */ 35 | if ((err = mpf_copy(a, &tmpx)) != MP_OKAY) { goto __ERR; } 36 | tmpx.radix = b->radix; 37 | if ((err = mpf_normalize(&tmpx)) != MP_OKAY) { goto __ERR; } 38 | 39 | /* the result starts off at a as we skip a term in the series */ 40 | if ((err = mpf_copy(&tmpx, &res)) != MP_OKAY) { goto __ERR; } 41 | 42 | /* this is the denom counter. Goes up by two per pass */ 43 | n = 1; 44 | 45 | /* we alternate between adding and subtracting */ 46 | oddeven = 1; 47 | 48 | /* get number of iterations */ 49 | itts = mpf_iterations(b); 50 | 51 | while (itts-- > 0) { 52 | if ((err = mpf_copy(&res, &oldval)) != MP_OKAY) { goto __ERR; } 53 | 54 | /* compute 1/(2n)! from 1/(2(n-1))! by multiplying by (1/n)(1/(n+1)) */ 55 | if ((err = mpf_const_d(&tmp, ++n)) != MP_OKAY) { goto __ERR; } 56 | if ((err = mpf_inv(&tmp, &tmp)) != MP_OKAY) { goto __ERR; } 57 | if ((err = mpf_mul(&tmpovern, &tmp, &tmpovern)) != MP_OKAY) { goto __ERR; } 58 | /* we do this twice */ 59 | if ((err = mpf_const_d(&tmp, ++n)) != MP_OKAY) { goto __ERR; } 60 | if ((err = mpf_inv(&tmp, &tmp)) != MP_OKAY) { goto __ERR; } 61 | if ((err = mpf_mul(&tmpovern, &tmp, &tmpovern)) != MP_OKAY) { goto __ERR; } 62 | 63 | /* now multiply sqr into tmpx */ 64 | if ((err = mpf_mul(&tmpx, &sqr, &tmpx)) != MP_OKAY) { goto __ERR; } 65 | 66 | /* now multiply the two */ 67 | if ((err = mpf_mul(&tmpx, &tmpovern, &tmp)) != MP_OKAY) { goto __ERR; } 68 | 69 | /* now depending on if this is even or odd we add/sub */ 70 | oddeven ^= 1; 71 | if (oddeven == 1) { 72 | if ((err = mpf_add(&res, &tmp, &res)) != MP_OKAY) { goto __ERR; } 73 | } else { 74 | if ((err = mpf_sub(&res, &tmp, &res)) != MP_OKAY) { goto __ERR; } 75 | } 76 | 77 | if (mpf_cmp(&res, &oldval) == MP_EQ) { 78 | break; 79 | } 80 | } 81 | mpf_exch(&res, b); 82 | __ERR: mpf_clear_multi(&oldval, &tmpx, &tmpovern, &tmp, &res, &sqr, NULL); 83 | return err; 84 | } 85 | -------------------------------------------------------------------------------- /mpf_sqr.c: -------------------------------------------------------------------------------- 1 | /* LibTomFloat, multiple-precision floating-point library 2 | * 3 | * LibTomFloat is a library that provides multiple-precision 4 | * floating-point artihmetic as well as trigonometric functionality. 5 | * 6 | * This library requires the public domain LibTomMath to be installed. 7 | * 8 | * This library is free for all purposes without any express 9 | * gurantee it works 10 | * 11 | * Tom St Denis, tomstdenis@iahu.ca, http://float.libtomcrypt.org 12 | */ 13 | #include 14 | 15 | int mpf_sqr(mp_float *a, mp_float *b) 16 | { 17 | int err; 18 | if ((err = mp_sqr(&(a->mantissa), &(b->mantissa))) != MP_OKAY) { 19 | return err; 20 | } 21 | b->exp = 2 * a->exp; 22 | return mpf_normalize(b); 23 | } 24 | -------------------------------------------------------------------------------- /mpf_sqrt.c: -------------------------------------------------------------------------------- 1 | /* LibTomFloat, multiple-precision floating-point library 2 | * 3 | * LibTomFloat is a library that provides multiple-precision 4 | * floating-point artihmetic as well as trigonometric functionality. 5 | * 6 | * This library requires the public domain LibTomMath to be installed. 7 | * 8 | * This library is free for all purposes without any express 9 | * gurantee it works 10 | * 11 | * Tom St Denis, tomstdenis@iahu.ca, http://float.libtomcrypt.org 12 | */ 13 | #include 14 | 15 | /* compute using sqrt(x) = y_{n+1} = 0.5 * (y_{n} + x/y_{n}) */ 16 | int mpf_sqrt(mp_float *a, mp_float *b) 17 | { 18 | mp_float oldval, tmp, res; 19 | int err, itts; 20 | 21 | /* make sure it's positive */ 22 | if (a->mantissa.sign == MP_NEG) { 23 | return MP_VAL; 24 | } 25 | 26 | /* let's roll */ 27 | if ((err = mpf_init_multi(b->radix, &oldval, &tmp, &res, NULL)) != MP_OKAY) { 28 | return err; 29 | } 30 | 31 | /* get copy of a and make reasonable guestimte towards the sqrt */ 32 | if ((err = mpf_copy(a, &res)) != MP_OKAY) { goto __ERR; } 33 | mp_rshd(&(res.mantissa), res.mantissa.used >> 1); 34 | res.exp = res.exp / 2; 35 | if ((err = mpf_normalize_to(&res, b->radix)) != MP_OKAY) { goto __ERR; } 36 | 37 | /* number of iterations */ 38 | itts = mpf_iterations(b); 39 | 40 | while (itts--) { 41 | if ((err = mpf_copy(&res, &oldval)) != MP_OKAY) { goto __ERR; } 42 | 43 | /* compute x/res */ 44 | if ((err = mpf_div(a, &res, &tmp)) != MP_OKAY) { goto __ERR; } 45 | /* res + x/res */ 46 | if ((err = mpf_add(&res, &tmp, &res)) != MP_OKAY) { goto __ERR; } 47 | /* 0.5 * (res + x/res) */ 48 | if ((err = mpf_div_2(&res, &res)) != MP_OKAY) { goto __ERR; } 49 | 50 | if (mpf_cmp(&res, &oldval) == MP_EQ) { 51 | break; 52 | } 53 | } 54 | 55 | mpf_exch(&res, b); 56 | __ERR: mpf_clear_multi(&oldval, &tmp, &res, NULL); 57 | return err; 58 | } 59 | 60 | -------------------------------------------------------------------------------- /mpf_sub.c: -------------------------------------------------------------------------------- 1 | /* LibTomFloat, multiple-precision floating-point library 2 | * 3 | * LibTomFloat is a library that provides multiple-precision 4 | * floating-point artihmetic as well as trigonometric functionality. 5 | * 6 | * This library requires the public domain LibTomMath to be installed. 7 | * 8 | * This library is free for all purposes without any express 9 | * gurantee it works 10 | * 11 | * Tom St Denis, tomstdenis@iahu.ca, http://float.libtomcrypt.org 12 | */ 13 | #include 14 | 15 | int mpf_sub(mp_float *a, mp_float *b, mp_float *c) 16 | { 17 | int err; 18 | mp_float tmp; 19 | long diff; 20 | 21 | if (mpf_iszero(a)) { 22 | diff = c->radix; 23 | if ((err = mpf_neg(b, c)) != MP_OKAY) { 24 | return err; 25 | } 26 | return mpf_normalize_to(c, diff); 27 | } else if (mpf_iszero(b)) { 28 | diff = c->radix; 29 | if ((err = mpf_copy(a, c)) != MP_OKAY) { 30 | return err; 31 | } 32 | return mpf_normalize_to(c, diff); 33 | } 34 | 35 | if (a->exp < b->exp) { 36 | /* tmp == a normalize to b's exp */ 37 | if ((err = mpf_init_copy(a, &tmp)) != MP_OKAY) { 38 | return err; 39 | } 40 | 41 | /* now make tmp.exp == b.exp by dividing tmp by 2^(b.exp - tmp.exp) */ 42 | diff = b->exp - tmp.exp; 43 | tmp.exp = b->exp; 44 | if ((err = mp_div_2d(&(tmp.mantissa), diff, (&tmp.mantissa), NULL)) != MP_OKAY) { goto __TMP; } 45 | if ((err = mp_sub(&(tmp.mantissa), &(b->mantissa), &(c->mantissa))) != MP_OKAY) { goto __TMP; } 46 | c->exp = b->exp; 47 | } else { 48 | /* tmp == b normalize to a's radix */ 49 | if ((err = mpf_init_copy(b, &tmp)) != MP_OKAY) { 50 | return err; 51 | } 52 | 53 | /* now make tmp.exp == a.exp by dividing tmp by 2^(a.exp - tmp.exp) */ 54 | diff = a->exp - tmp.exp; 55 | tmp.exp = a->exp; 56 | if ((err = mp_div_2d(&(tmp.mantissa), diff, (&tmp.mantissa), NULL)) != MP_OKAY) { goto __TMP; } 57 | if ((err = mp_sub(&(a->mantissa), &(tmp.mantissa), &(c->mantissa))) != MP_OKAY) { goto __TMP; } 58 | c->exp = a->exp; 59 | } 60 | 61 | err = mpf_normalize(c); 62 | 63 | __TMP: mpf_clear(&tmp); 64 | return err; 65 | } 66 | -------------------------------------------------------------------------------- /mpf_sub_d.c: -------------------------------------------------------------------------------- 1 | /* LibTomFloat, multiple-precision floating-point library 2 | * 3 | * LibTomFloat is a library that provides multiple-precision 4 | * floating-point artihmetic as well as trigonometric functionality. 5 | * 6 | * This library requires the public domain LibTomMath to be installed. 7 | * 8 | * This library is free for all purposes without any express 9 | * gurantee it works 10 | * 11 | * Tom St Denis, tomstdenis@iahu.ca, http://float.libtomcrypt.org 12 | */ 13 | #include 14 | 15 | int mpf_sub_d(mp_float *a, long b, mp_float *c) 16 | { 17 | int err; 18 | mp_float tmp; 19 | 20 | if ((err = mpf_init(&tmp, c->radix)) != MP_OKAY) { 21 | return err; 22 | } 23 | 24 | if ((err = mpf_const_d(&tmp, b)) != MP_OKAY) { goto __ERR; } 25 | err = mpf_sub(a, &tmp, c); 26 | 27 | __ERR: 28 | mpf_clear(&tmp); 29 | return err; 30 | } 31 | 32 | -------------------------------------------------------------------------------- /mpf_tan.c: -------------------------------------------------------------------------------- 1 | /* LibTomFloat, multiple-precision floating-point library 2 | * 3 | * LibTomFloat is a library that provides multiple-precision 4 | * floating-point artihmetic as well as trigonometric functionality. 5 | * 6 | * This library requires the public domain LibTomMath to be installed. 7 | * 8 | * This library is free for all purposes without any express 9 | * gurantee it works 10 | * 11 | * Tom St Denis, tomstdenis@iahu.ca, http://float.libtomcrypt.org 12 | */ 13 | #include 14 | 15 | /* tan = sin/cos, prolly fix this up later */ 16 | int mpf_tan(mp_float *a, mp_float *b) 17 | { 18 | int err; 19 | mp_float tmp; 20 | 21 | /* get cos of a */ 22 | if ((err = mpf_init(&tmp, b->radix)) != MP_OKAY) { 23 | return err; 24 | } 25 | if ((err = mpf_cos(a, &tmp)) != MP_OKAY) { goto __ERR; } 26 | 27 | /* now make it upside down ;-) (this should catch domain errors too) */ 28 | if ((err = mpf_inv(&tmp, &tmp)) != MP_OKAY) { goto __ERR; } 29 | 30 | /* put sin in b */ 31 | if ((err = mpf_sin(a, b)) != MP_OKAY) { goto __ERR; } 32 | 33 | /* multiply the two and we done */ 34 | err = mpf_mul(b, &tmp, b); 35 | 36 | __ERR: mpf_clear(&tmp); 37 | return err; 38 | } 39 | 40 | -------------------------------------------------------------------------------- /tomfloat.h: -------------------------------------------------------------------------------- 1 | /* LibTomFloat, multiple-precision floating-point library 2 | * 3 | * LibTomFloat is a library that provides multiple-precision 4 | * floating-point artihmetic as well as trigonometric functionality. 5 | * 6 | * This library requires the public domain LibTomMath to be installed. 7 | * 8 | * This library is free for all purposes without any express 9 | * gurantee it works 10 | * 11 | * Tom St Denis, tomstdenis@iahu.ca, http://float.libtomcrypt.org 12 | */ 13 | #ifndef TF_H_ 14 | #define TF_H_ 15 | 16 | #include 17 | 18 | /* this is mp_float type */ 19 | typedef struct { 20 | mp_int mantissa; 21 | long radix, /* how many bits for mantissa */ 22 | exp; /* current exponent, e.g. mantissa * 2^exp == number */ 23 | } mp_float; 24 | 25 | /* initializers */ 26 | int mpf_init(mp_float *a, long radix); 27 | void mpf_clear(mp_float *a); 28 | 29 | int mpf_init_multi(long radix, mp_float *a, ...); 30 | void mpf_clear_multi(mp_float *a, ...); 31 | 32 | int mpf_init_copy(mp_float *a, mp_float *b); 33 | 34 | int mpf_copy(mp_float *src, mp_float *dest); 35 | void mpf_exch(mp_float *a, mp_float *b); 36 | 37 | /* maintainers/misc */ 38 | int mpf_normalize(mp_float *a); 39 | int mpf_normalize_to(mp_float *a, long radix); 40 | int mpf_iterations(mp_float *a); 41 | 42 | /* constants */ 43 | int mpf_const_0(mp_float *a); /* valid zero */ 44 | int mpf_const_d(mp_float *a, long d); /* valid d */ 45 | int mpf_const_ln_d(mp_float *a, long b); /* a = ln(b) */ 46 | int mpf_const_sqrt_d(mp_float *a, long b); /* a = sqrt(b); */ 47 | 48 | /* math constants as they appear in math.h */ 49 | int mpf_const_e(mp_float *a); /* e */ 50 | int mpf_const_l2e(mp_float *a); /* log_2 e */ 51 | int mpf_const_l10e(mp_float *a); /* log_10 e */ 52 | int mpf_const_le2(mp_float *a); /* log_e 2 */ 53 | int mpf_const_pi(mp_float *a); /* Pi */ 54 | int mpf_const_pi2(mp_float *a); /* Pi/2 */ 55 | int mpf_const_pi4(mp_float *a); /* Pi/4 */ 56 | int mpf_const_1pi(mp_float *a); /* 1/Pi */ 57 | int mpf_const_2pi(mp_float *a); /* 2/Pi */ 58 | int mpf_const_2rpi(mp_float *a); /* 2/sqrt(Pi) */ 59 | int mpf_const_r2(mp_float *a); /* sqrt(2) */ 60 | int mpf_const_1r2(mp_float *a); /* 1/sqrt(2) */ 61 | 62 | /* sign operators */ 63 | int mpf_abs(mp_float *a, mp_float *b); /* absolute */ 64 | int mpf_neg(mp_float *a, mp_float *b); /* negation */ 65 | 66 | /* basic math */ 67 | int mpf_mul_2(mp_float *a, mp_float *b); /* b = 2a */ 68 | int mpf_div_2(mp_float *a, mp_float *b); /* b = a/2 */ 69 | int mpf_add(mp_float *a, mp_float *b, mp_float *c); /* c = a + b */ 70 | int mpf_sub(mp_float *a, mp_float *b, mp_float *c); /* c = a - b */ 71 | int mpf_mul(mp_float *a, mp_float *b, mp_float *c); /* c = a * b */ 72 | int mpf_div(mp_float *a, mp_float *b, mp_float *c); /* c = a / b */ 73 | int mpf_sqr(mp_float *a, mp_float *b); /* b = a^2 */ 74 | 75 | int mpf_add_d(mp_float *a, long b, mp_float *c); /* c = a + b */ 76 | int mpf_sub_d(mp_float *a, long b, mp_float *c); /* c = a - b */ 77 | int mpf_mul_d(mp_float *a, long b, mp_float *c); /* c = a * b */ 78 | int mpf_div_d(mp_float *a, long b, mp_float *c); /* c = a / b */ 79 | 80 | /* compares */ 81 | int mpf_cmp(mp_float *a, mp_float *b); 82 | int mpf_cmp_d(mp_float *a, long b, int *res); 83 | #define mpf_iszero(a) mp_iszero(&((a)->mantissa)) 84 | 85 | /* Algebra */ 86 | int mpf_exp(mp_float *a, mp_float *b); /* b = e^a */ 87 | int mpf_pow(mp_float *a, mp_float *b, mp_float *c); /* c = a^b */ 88 | int mpf_ln(mp_float *a, mp_float *b); /* b = ln a */ 89 | int mpf_invsqrt(mp_float *a, mp_float *b); /* b = 1/sqrt(a) */ 90 | int mpf_inv(mp_float *a, mp_float *b); /* b = 1/a */ 91 | int mpf_sqrt(mp_float *a, mp_float *b); /* b = sqrt(a) */ 92 | 93 | /* Trig */ 94 | int mpf_cos(mp_float *a, mp_float *b); /* b = cos(a) */ 95 | int mpf_sin(mp_float *a, mp_float *b); /* b = sin(a) */ 96 | int mpf_tan(mp_float *a, mp_float *b); /* b = tan(a) */ 97 | int mpf_acos(mp_float *a, mp_float *b); /* b = acos(a) */ 98 | int mpf_asin(mp_float *a, mp_float *b); /* b = asin(a) */ 99 | int mpf_atan(mp_float *a, mp_float *b); /* b = atan(a) */ 100 | 101 | /* ASCII <=> mp_float conversions */ 102 | char *mpf_to_string(mp_float *a, mp_digit radix); 103 | int mpf_from_string(mp_float *a, const char *str, mp_digit radix); 104 | 105 | #endif 106 | --------------------------------------------------------------------------------