|
Packit |
5c3484 |
/* mpz_mul_ui/si (product, multiplier, small_multiplicand) -- Set PRODUCT to
|
|
Packit |
5c3484 |
MULTIPLICATOR times SMALL_MULTIPLICAND.
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
Copyright 1991, 1993, 1994, 1996, 2000-2002, 2005, 2008, 2012 Free Software
|
|
Packit |
5c3484 |
Foundation, Inc.
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
This file is part of the GNU MP Library.
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
The GNU MP Library is free software; you can redistribute it and/or modify
|
|
Packit |
5c3484 |
it under the terms of either:
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
* the GNU Lesser General Public License as published by the Free
|
|
Packit |
5c3484 |
Software Foundation; either version 3 of the License, or (at your
|
|
Packit |
5c3484 |
option) any later version.
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
or
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
* the GNU General Public License as published by the Free Software
|
|
Packit |
5c3484 |
Foundation; either version 2 of the License, or (at your option) any
|
|
Packit |
5c3484 |
later version.
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
or both in parallel, as here.
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
The GNU MP Library is distributed in the hope that it will be useful, but
|
|
Packit |
5c3484 |
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
Packit |
5c3484 |
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
Packit |
5c3484 |
for more details.
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
You should have received copies of the GNU General Public License and the
|
|
Packit |
5c3484 |
GNU Lesser General Public License along with the GNU MP Library. If not,
|
|
Packit |
5c3484 |
see https://www.gnu.org/licenses/. */
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
#include "gmp.h"
|
|
Packit |
5c3484 |
#include "gmp-impl.h"
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
#ifdef OPERATION_mul_si
|
|
Packit |
5c3484 |
#define FUNCTION mpz_mul_si
|
|
Packit |
5c3484 |
#define MULTIPLICAND_UNSIGNED
|
|
Packit |
5c3484 |
#define MULTIPLICAND_ABS(x) ABS_CAST(unsigned long, (x))
|
|
Packit |
5c3484 |
#endif
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
#ifdef OPERATION_mul_ui
|
|
Packit |
5c3484 |
#define FUNCTION mpz_mul_ui
|
|
Packit |
5c3484 |
#define MULTIPLICAND_UNSIGNED unsigned
|
|
Packit |
5c3484 |
#define MULTIPLICAND_ABS(x) x
|
|
Packit |
5c3484 |
#endif
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
#ifndef FUNCTION
|
|
Packit |
5c3484 |
Error, error, unrecognised OPERATION
|
|
Packit |
5c3484 |
#endif
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
void
|
|
Packit |
5c3484 |
FUNCTION (mpz_ptr prod, mpz_srcptr mult,
|
|
Packit |
5c3484 |
MULTIPLICAND_UNSIGNED long int small_mult)
|
|
Packit |
5c3484 |
{
|
|
Packit |
5c3484 |
mp_size_t size;
|
|
Packit |
5c3484 |
mp_size_t sign_product;
|
|
Packit |
5c3484 |
mp_limb_t sml;
|
|
Packit |
5c3484 |
mp_limb_t cy;
|
|
Packit |
5c3484 |
mp_ptr pp;
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
sign_product = SIZ(mult);
|
|
Packit |
5c3484 |
if (sign_product == 0 || small_mult == 0)
|
|
Packit |
5c3484 |
{
|
|
Packit |
5c3484 |
SIZ(prod) = 0;
|
|
Packit |
5c3484 |
return;
|
|
Packit |
5c3484 |
}
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
size = ABS (sign_product);
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
sml = MULTIPLICAND_ABS (small_mult);
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
if (sml <= GMP_NUMB_MAX)
|
|
Packit |
5c3484 |
{
|
|
Packit |
5c3484 |
pp = MPZ_REALLOC (prod, size + 1);
|
|
Packit |
5c3484 |
cy = mpn_mul_1 (pp, PTR(mult), size, sml);
|
|
Packit |
5c3484 |
pp[size] = cy;
|
|
Packit |
5c3484 |
size += cy != 0;
|
|
Packit |
5c3484 |
}
|
|
Packit |
5c3484 |
#if GMP_NAIL_BITS != 0
|
|
Packit |
5c3484 |
else
|
|
Packit |
5c3484 |
{
|
|
Packit |
5c3484 |
/* Operand too large for the current nails size. Use temporary for
|
|
Packit |
5c3484 |
intermediate products, to allow prod and mult being identical. */
|
|
Packit |
5c3484 |
mp_ptr tp;
|
|
Packit |
5c3484 |
TMP_DECL;
|
|
Packit |
5c3484 |
TMP_MARK;
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
tp = TMP_ALLOC_LIMBS (size + 2);
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
/* Use, maybe, mpn_mul_2? */
|
|
Packit |
5c3484 |
cy = mpn_mul_1 (tp, PTR(mult), size, sml & GMP_NUMB_MASK);
|
|
Packit |
5c3484 |
tp[size] = cy;
|
|
Packit |
5c3484 |
cy = mpn_addmul_1 (tp + 1, PTR(mult), size, sml >> GMP_NUMB_BITS);
|
|
Packit |
5c3484 |
tp[size + 1] = cy;
|
|
Packit |
5c3484 |
size += 2;
|
|
Packit |
5c3484 |
MPN_NORMALIZE_NOT_ZERO (tp, size); /* too general, need to trim one or two limb */
|
|
Packit |
5c3484 |
pp = MPZ_REALLOC (prod, size);
|
|
Packit |
5c3484 |
MPN_COPY (pp, tp, size);
|
|
Packit |
5c3484 |
TMP_FREE;
|
|
Packit |
5c3484 |
}
|
|
Packit |
5c3484 |
#endif
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
SIZ(prod) = ((sign_product < 0) ^ (small_mult < 0)) ? -size : size;
|
|
Packit |
5c3484 |
}
|