Annotation of OpenXM_contrib/gmp/mpfr/factorial.c, Revision 1.1.1.1
1.1 ohara 1: /* mpfr_fac_ui -- factorial of a non-negative integer
2:
3: Copyright 2001 Free Software Foundation, Inc.
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 Lesser General Public License as published by
9: the Free Software Foundation; either version 2.1 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 Lesser General Public
15: License for more details.
16:
17: You should have received a copy of the GNU Lesser 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 "gmp.h"
23: #include "gmp-impl.h"
24: #include "mpfr.h"
25: #include "mpfr-impl.h"
26:
27: /* The computation of n! is done by
28:
29: n!=prod^{n}_{i=1}i
30: */
31:
32: int
33: mpfr_fac_ui (mpfr_ptr y, unsigned long int x , mp_rnd_t rnd_mode)
34: {
35:
36: /****** Declaration ******/
37:
38: mpfr_t t; /* Variable of Intermediary Calculation*/
39: int i;
40: int round, inexact = 0;
41: int boucle = 1;
42:
43: mp_prec_t Ny; /* Precision of output variable */
44: mp_prec_t Nt; /* Precision of Intermediary Calculation variable */
45: mp_prec_t err; /* Precision of error */
46:
47: /***** test x = 0 ******/
48:
49: if (x == 0)
50: {
51: mpfr_set_ui (y, 1, GMP_RNDN); /* 0! = 1 */
52: return 0;
53: }
54: else
55: {
56: /* Initialisation of the Precision */
57: Ny=MPFR_PREC(y);
58:
59: Nt=Ny+2*(int)_mpfr_ceil_log2((double)x)+10; /*compute the size of intermediary variable */
60:
61:
62: mpfr_init2(t, Nt);/* initialise of intermediary variable */
63:
64: while (boucle)
65: {
66: inexact = mpfr_set_ui (t, 1, GMP_RNDZ);
67:
68: for(i=2;i<=x;i++) /* compute factorial */
69: {
70: round = mpfr_mul_ui (t, t, i, GMP_RNDZ);
71: /* assume the first inexact product gives the sign
72: of difference: is that always correct? */
73: if (inexact == 0)
74: inexact = round;
75: }
76:
77: err = Nt - 1 - (int) _mpfr_ceil_log2 ((double) Nt);
78:
79: round = !inexact || mpfr_can_round (t,err,GMP_RNDZ,rnd_mode,Ny);
80:
81: if (round)
82: {
83: round = mpfr_set (y, t, rnd_mode);
84: if (inexact == 0)
85: inexact = round;
86: boucle=0;
87: }
88: else
89: {
90: Nt=Nt+10;
91: /*initialise of intermediary variable */
92: mpfr_set_prec(t, Nt);
93: }
94: }
95:
96: mpfr_clear(t);
97: return inexact;
98:
99: }
100: }
101:
102:
103:
104:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>