/* mpn_udiv_w_sdiv -- implement udiv_qrnnd on machines with only signed
division .
Contributed by Peter L . Montgomery .
THIS IS AN INTERNAL FUNCTION WITH A MUTABLE INTERFACE . IT IS ONLY SAFE
TO REACH THIS FUNCTION THROUGH DOCUMENTED INTERFACES . IN FACT , IT IS
ALMOST GUARANTEED THAT THIS FUNCTION WILL CHANGE OR DISAPPEAR IN A FUTURE
GNU MP RELEASE .
Copyright 1992 , 1994 , 1996 , 2000 , 2011 , 2012 Free Software Foundation , Inc .
This file is part of the GNU MP Library .
The GNU MP Library is free software ; you can redistribute it and / or modify
it under the terms of either :
* the GNU Lesser General Public License as published by the Free
Software Foundation ; either version 3 of the License , or ( at your
option ) any later version .
or
* the GNU General Public License as published by the Free Software
Foundation ; either version 2 of the License , or ( at your option ) any
later version .
or both in parallel , as here .
The GNU MP Library is distributed in the hope that it will be useful , but
WITHOUT ANY WARRANTY ; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE . See the GNU General Public License
for more details .
You should have received copies of the GNU General Public License and the
GNU Lesser General Public License along with the GNU MP Library . If not ,
see https://www.gnu.org/licenses/. */
#include "gmp-impl.h"
#include "longlong.h"
mp_limb_t
mpn_udiv_w_sdiv (mp_limb_t *rp, mp_limb_t a1, mp_limb_t a0, mp_limb_t d)
{
mp_limb_t q, r;
mp_limb_t c0, c1, b1;
ASSERT (d !=
0 );
ASSERT (a1 < d);
if ((mp_limb_signed_t) d >=
0 )
{
if (a1 < d - a1 - (a0 >> (GMP_LIMB_BITS -
1 )))
{
/* dividend, divisor, and quotient are nonnegative */
sdiv_qrnnd (q, r, a1, a0, d);
}
else
{
/* Compute c1*2^32 + c0 = a1*2^32 + a0 - 2^31*d */
sub_ddmmss (c1, c0, a1, a0, d >>
1 , d << (GMP_LIMB_BITS -
1 ));
/* Divide (c1*2^32 + c0) by d */
sdiv_qrnnd (q, r, c1, c0, d);
/* Add 2^31 to quotient */
q += (mp_limb_t)
1 << (GMP_LIMB_BITS -
1 );
}
}
else
{
b1 = d >>
1 ;
/* d/2, between 2^30 and 2^31 - 1 */
c1 = a1 >>
1 ;
/* A/2 */
c0 = (a1 << (GMP_LIMB_BITS -
1 )) + (a0 >>
1 );
if (a1 < b1)
/* A < 2^32*b1, so A/2 < 2^31*b1 */
{
sdiv_qrnnd (q, r, c1, c0, b1);
/* (A/2) / (d/2) */
r =
2 *r + (a0 &
1 );
/* Remainder from A/(2*b1) */
if ((d &
1 ) !=
0 )
{
if (r >= q)
r = r - q;
else if (q - r <= d)
{
r = r - q + d;
q--;
}
else
{
r = r - q +
2 *d;
q -=
2 ;
}
}
}
else if (c1 < b1)
/* So 2^31 <= (A/2)/b1 < 2^32 */
{
c1 = (b1 -
1 ) - c1;
c0 = ~c0;
/* logical NOT */
sdiv_qrnnd (q, r, c1, c0, b1);
/* (A/2) / (d/2) */
q = ~q;
/* (A/2)/b1 */
r = (b1 -
1 ) - r;
r =
2 *r + (a0 &
1 );
/* A/(2*b1) */
if ((d &
1 ) !=
0 )
{
if (r >= q)
r = r - q;
else if (q - r <= d)
{
r = r - q + d;
q--;
}
else
{
r = r - q +
2 *d;
q -=
2 ;
}
}
}
else /* Implies c1 = b1 */
{
/* Hence a1 = d - 1 = 2*b1 - 1 */
if (a0 >= -d)
{
q = -CNST_LIMB(
1 );
r = a0 + d;
}
else
{
q = -CNST_LIMB(
2 );
r = a0 +
2 *d;
}
}
}
*rp = r;
return q;
}
Messung V0.5 in Prozent C=95 H=100 G=97
¤ Dauer der Verarbeitung: 0.5 Sekunden
¤
*© Formatika GbR, Deutschland