Annotation of OpenXM_contrib/gmp/mpz/mul_i.h, Revision 1.1.1.1
1.1 ohara 1: /* mpz_mul_ui/si (product, multiplier, small_multiplicand) -- Set PRODUCT to
2: MULTIPLICATOR times SMALL_MULTIPLICAND.
3:
4: Copyright 1991, 1993, 1994, 1996, 2000, 2001, 2002 Free Software Foundation,
5: Inc.
6:
7: This file is part of the GNU MP Library.
8:
9: The GNU MP Library is free software; you can redistribute it and/or modify
10: it under the terms of the GNU Lesser General Public License as published by
11: the Free Software Foundation; either version 2.1 of the License, or (at your
12: option) any later version.
13:
14: The GNU MP Library is distributed in the hope that it will be useful, but
15: WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16: or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
17: License for more details.
18:
19: You should have received a copy of the GNU Lesser General Public License
20: along with the GNU MP Library; see the file COPYING.LIB. If not, write to
21: the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
22: MA 02111-1307, USA. */
23:
24: #include "gmp.h"
25: #include "gmp-impl.h"
26:
27:
28: #ifdef OPERATION_mul_si
29: #define FUNCTION mpz_mul_si
30: #define MULTIPLICAND_UNSIGNED
31: #define MULTIPLICAND_ABS(x) ((unsigned long) ABS(x))
32: #endif
33:
34: #ifdef OPERATION_mul_ui
35: #define FUNCTION mpz_mul_ui
36: #define MULTIPLICAND_UNSIGNED unsigned
37: #define MULTIPLICAND_ABS(x) x
38: #endif
39:
40: #ifndef FUNCTION
41: Error, error, unrecognised OPERATION
42: #endif
43:
44:
45: void
46: FUNCTION (mpz_ptr prod, mpz_srcptr mult,
47: MULTIPLICAND_UNSIGNED long int small_mult)
48: {
49: mp_size_t size = SIZ(mult);
50: mp_size_t sign_product = size;
51: mp_limb_t sml;
52: mp_limb_t cy;
53: mp_ptr pp;
54:
55: if (size == 0 || small_mult == 0)
56: {
57: SIZ(prod) = 0;
58: return;
59: }
60:
61: size = ABS (size);
62:
63: sml = MULTIPLICAND_ABS (small_mult);
64:
65: if (small_mult <= GMP_NUMB_MAX)
66: {
67: MPZ_REALLOC (prod, size + 1);
68: pp = PTR(prod);
69: cy = mpn_mul_1 (pp, PTR(mult), size, sml & GMP_NUMB_MASK);
70: pp[size] = cy;
71: size += cy != 0;
72: }
73: #if GMP_NAIL_BITS != 0
74: else
75: {
76: /* Operand too large for the current nails size. Use temporary for
77: intermediate products, to allow prod and mult being identical. */
78: mp_ptr tp;
79: TMP_DECL (mark);
80: TMP_MARK (mark);
81:
82: tp = TMP_ALLOC_LIMBS (size + 2);
83:
84: cy = mpn_mul_1 (tp, PTR(mult), size, sml & GMP_NUMB_MASK);
85: tp[size] = cy;
86: cy = mpn_addmul_1 (tp + 1, PTR(mult), size, sml >> GMP_NUMB_BITS);
87: tp[size + 1] = cy;
88: size += 2;
89: MPN_NORMALIZE_NOT_ZERO (tp, size); /* too general, need to trim one or two limb */
90: MPZ_REALLOC (prod, size);
91: pp = PTR(prod);
92: MPN_COPY (pp, tp, size);
93: TMP_FREE (mark);
94: }
95: #endif
96:
97: SIZ(prod) = ((sign_product < 0) ^ (small_mult < 0)) ? -size : size;
98: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>