[BACK]Return to log2.c CVS log [TXT][DIR] Up to [local] / OpenXM_contrib / gmp / mpfr

Annotation of OpenXM_contrib/gmp/mpfr/log2.c, Revision 1.1

1.1     ! maekawa     1: /* mpfr_log2 -- compute natural logarithm of 2
        !             2:
        !             3: Copyright (C) 1999 PolKA project, Inria Lorraine and Loria
        !             4:
        !             5: This file is part of the MPFR Library.
        !             6:
        !             7: The MPFR Library is free software; you can redistribute it and/or modify
        !             8: it under the terms of the GNU Library General Public License as published by
        !             9: the Free Software Foundation; either version 2 of the License, or (at your
        !            10: option) any later version.
        !            11:
        !            12: The MPFR Library is distributed in the hope that it will be useful, but
        !            13: WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
        !            14: or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
        !            15: License for more details.
        !            16:
        !            17: You should have received a copy of the GNU Library General Public License
        !            18: along with the MPFR Library; see the file COPYING.LIB.  If not, write to
        !            19: the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
        !            20: MA 02111-1307, USA. */
        !            21:
        !            22: #include <stdio.h>
        !            23: #include <math.h>
        !            24: #include "gmp.h"
        !            25: #include "gmp-impl.h"
        !            26: #include "longlong.h"
        !            27: #include "mpfr.h"
        !            28:
        !            29: mpfr_t __mpfr_log2; /* stored value of log(2) with rnd_mode=GMP_RNDZ */
        !            30: int __mpfr_log2_prec=0; /* precision of stored value */
        !            31:
        !            32: /* set x to log(2) rounded to precision PREC(x) with direction rnd_mode
        !            33:
        !            34:    use formula log(2) = sum(1/k/2^k, k=1..infinity)
        !            35:
        !            36:    whence 2^N*log(2) = S(N) + R(N)
        !            37:
        !            38:    where S(N) = sum(2^(N-k)/k, k=1..N-1)
        !            39:    and   R(N) = sum(1/k/2^(k-N), k=N..infinity) < 2/N
        !            40:
        !            41:    Let S'(N) = sum(floor(2^(N-k)/k), k=1..N-1)
        !            42:
        !            43:    Then 2^N*log(2)-S'(N) <= N-1+2/N <= N for N>=2.
        !            44: */
        !            45: void
        !            46: #if __STDC__
        !            47: mpfr_log2(mpfr_ptr x, unsigned char rnd_mode)
        !            48: #else
        !            49: mpfr_log2(x, rnd_mode) mpfr_ptr x; unsigned char rnd_mode;
        !            50: #endif
        !            51: {
        !            52:   int N, oldN, k, precx; mpz_t s, t, u;
        !            53:
        !            54:   precx = PREC(x);
        !            55:
        !            56:   /* has stored value enough precision ? */
        !            57:   if (precx <= __mpfr_log2_prec) {
        !            58:     if (rnd_mode==GMP_RNDZ || rnd_mode==GMP_RNDD ||
        !            59:        mpfr_can_round(__mpfr_log2, __mpfr_log2_prec, GMP_RNDZ, rnd_mode, precx))
        !            60:       {
        !            61:        mpfr_set(x, __mpfr_log2, rnd_mode); return;
        !            62:       }
        !            63:   }
        !            64:
        !            65:   /* need to recompute */
        !            66:   N=2;
        !            67:   do {
        !            68:     oldN = N;
        !            69:     N = precx + (int)ceil(log((double)N)/log(2.0));
        !            70:   } while (N != oldN);
        !            71:   mpz_init_set_ui(s,0);
        !            72:   mpz_init(u);
        !            73:   mpz_init_set_ui(t,1);
        !            74: #if 0
        !            75:   /* use log(2) = sum(1/k/2^k, k=1..infinity) */
        !            76:   mpz_mul_2exp(t, t, N);
        !            77:   for (k=1;k<N;k++) {
        !            78:     mpz_div_2exp(t, t, 1);
        !            79:     mpz_fdiv_q_ui(u, t, k);
        !            80:     mpz_add(s, s, u);
        !            81:   }
        !            82: #else
        !            83:   /* use log(2) = sum((6*k-1)/(2*k^2-k)/2^(2*k+1), k=1..infinity) */
        !            84:   mpz_mul_2exp(t, t, N-1);
        !            85:   for (k=1;k<N/2;k++) {
        !            86:     mpz_div_2exp(t, t, 2);
        !            87:     mpz_mul_ui(u, t, 6*k-1);
        !            88:     mpz_fdiv_q_ui(u, u, k*(2*k-1));
        !            89:     mpz_add(s, s, u);
        !            90:   }
        !            91: #endif
        !            92:   mpfr_set_z(x, s, rnd_mode);
        !            93:   EXP(x) -= N;
        !            94:
        !            95:   /* stored computed value */
        !            96:   if (__mpfr_log2_prec==0) mpfr_init2(__mpfr_log2, precx);
        !            97:   else mpfr_set_prec(__mpfr_log2, precx);
        !            98:   mpfr_set(__mpfr_log2, x, GMP_RNDZ);
        !            99:   __mpfr_log2_prec=precx;
        !           100:
        !           101:   mpz_clear(s); mpz_clear(t); mpz_clear(u);
        !           102: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>