/* mpn_invert_limb -- Invert a normalized limb.
Copyright 1991 , 2000 , 2001 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"
/*
This is needed to make configure define HAVE_NATIVE_mpn_invert_limb :
PROLOGUE ( mpn_invert_limb )
*/
static const unsigned short int approx_tab[
0 x100] =
{
/* 0x400, */
0 x3ff,
0 x3fc,
0 x3f8,
0 x3f4,
0 x3f0,
0 x3ec,
0 x3e8,
0 x3e4,
0 x3e0,
0 x3dd,
0 x3d9,
0 x3d5,
0 x3d2,
0 x3ce,
0 x3ca,
0 x3c7,
0 x3c3,
0 x3c0,
0 x3bc,
0 x3b9,
0 x3b5,
0 x3b2,
0 x3ae,
0 x3ab,
0 x3a8,
0 x3a4,
0 x3a1,
0 x39e,
0 x39b,
0 x397,
0 x394,
0 x391,
0 x38e,
0 x38b,
0 x387,
0 x384,
0 x381,
0 x37e,
0 x37b,
0 x378,
0 x375,
0 x372,
0 x36f,
0 x36c,
0 x369,
0 x366,
0 x364,
0 x361,
0 x35e,
0 x35b,
0 x358,
0 x355,
0 x353,
0 x350,
0 x34d,
0 x34a,
0 x348,
0 x345,
0 x342,
0 x340,
0 x33d,
0 x33a,
0 x338,
0 x335,
0 x333,
0 x330,
0 x32e,
0 x32b,
0 x329,
0 x326,
0 x324,
0 x321,
0 x31f,
0 x31c,
0 x31a,
0 x317,
0 x315,
0 x313,
0 x310,
0 x30e,
0 x30c,
0 x309,
0 x307,
0 x305,
0 x303,
0 x300,
0 x2fe,
0 x2fc,
0 x2fa,
0 x2f7,
0 x2f5,
0 x2f3,
0 x2f1,
0 x2ef,
0 x2ec,
0 x2ea,
0 x2e8,
0 x2e6,
0 x2e4,
0 x2e2,
0 x2e0,
0 x2de,
0 x2dc,
0 x2da,
0 x2d8,
0 x2d6,
0 x2d4,
0 x2d2,
0 x2d0,
0 x2ce,
0 x2cc,
0 x2ca,
0 x2c8,
0 x2c6,
0 x2c4,
0 x2c2,
0 x2c0,
0 x2be,
0 x2bc,
0 x2bb,
0 x2b9,
0 x2b7,
0 x2b5,
0 x2b3,
0 x2b1,
0 x2b0,
0 x2ae,
0 x2ac,
0 x2aa,
0 x2a8,
0 x2a7,
0 x2a5,
0 x2a3,
0 x2a1,
0 x2a0,
0 x29e,
0 x29c,
0 x29b,
0 x299,
0 x297,
0 x295,
0 x294,
0 x292,
0 x291,
0 x28f,
0 x28d,
0 x28c,
0 x28a,
0 x288,
0 x287,
0 x285,
0 x284,
0 x282,
0 x280,
0 x27f,
0 x27d,
0 x27c,
0 x27a,
0 x279,
0 x277,
0 x276,
0 x274,
0 x273,
0 x271,
0 x270,
0 x26e,
0 x26d,
0 x26b,
0 x26a,
0 x268,
0 x267,
0 x265,
0 x264,
0 x263,
0 x261,
0 x260,
0 x25e,
0 x25d,
0 x25c,
0 x25a,
0 x259,
0 x257,
0 x256,
0 x255,
0 x253,
0 x252,
0 x251,
0 x24f,
0 x24e,
0 x24d,
0 x24b,
0 x24a,
0 x249,
0 x247,
0 x246,
0 x245,
0 x243,
0 x242,
0 x241,
0 x240,
0 x23e,
0 x23d,
0 x23c,
0 x23b,
0 x239,
0 x238,
0 x237,
0 x236,
0 x234,
0 x233,
0 x232,
0 x231,
0 x230,
0 x22e,
0 x22d,
0 x22c,
0 x22b,
0 x22a,
0 x229,
0 x227,
0 x226,
0 x225,
0 x224,
0 x223,
0 x222,
0 x220,
0 x21f,
0 x21e,
0 x21d,
0 x21c,
0 x21b,
0 x21a,
0 x219,
0 x218,
0 x216,
0 x215,
0 x214,
0 x213,
0 x212,
0 x211,
0 x210,
0 x20f,
0 x20e,
0 x20d,
0 x20c,
0 x20b,
0 x20a,
0 x209,
0 x208,
0 x207,
0 x206,
0 x205,
0 x204,
0 x203,
0 x202,
0 x201,
};
/* iteration: z = 2z-(z**2)d */
mp_limb_t
mpn_invert_limb (mp_limb_t d)
{
mp_limb_t z, z2l, z2h, tl, th;
mp_limb_t xh, xl;
mp_limb_t zh, zl;
#if GMP_LIMB_BITS ==
32
z = approx_tab[(d >>
23 ) -
0 x100] <<
6 ;
/* z < 2^16 */
z2l = z * z;
/* z2l < 2^32 */
umul_ppmm (th, tl, z2l, d);
z = (z <<
17 ) - (th <<
1 );
#endif
#if GMP_LIMB_BITS ==
64
z = approx_tab[(d >>
55 ) -
0 x100] <<
6 ;
/* z < 2^16 */
z2l = z * z;
/* z2l < 2^32 */
th = z2l * (d >>
32 );
/* th < 2^64 */
z = (z <<
17 ) - (th >>
31 );
/* z < 2^32 */
z2l = z * z;
umul_ppmm (th, tl, z2l, d);
z = (z <<
33 ) - (th <<
1 );
#endif
umul_ppmm (z2h, z2l, z, z);
umul_ppmm (th, tl, z2h, d);
umul_ppmm (xh, xl, z2l, d);
tl += xh;
th += tl < xh;
th = (th <<
2 ) | (tl >> GMP_LIMB_BITS -
2 );
tl = tl <<
2 ;
sub_ddmmss (zh, zl, z <<
2 ,
0 , th, tl);
umul_ppmm (xh, xl, d, zh);
xh += d;
/* add_ssaaaa (xh, xl, xh, xl, d, 0); */
if (~xh !=
0 )
{
add_ssaaaa (xh, xl, xh, xl,
0 , d);
zh++;
}
add_ssaaaa (xh, xl, xh, xl,
0 , d);
if (xh !=
0 )
zh++;
return zh;
}
Messung V0.5 in Prozent C=92 H=100 G=95
¤ Dauer der Verarbeitung: 0.9 Sekunden
(vorverarbeitet am 2026-06-10)
¤
*© Formatika GbR, Deutschland