github.com/aergoio/aergo@v1.3.1/libtool/src/gmp-6.1.2/mpn/generic/hgcd2_jacobi.c (about)

     1  /* hgcd2_jacobi.c
     2  
     3     THE FUNCTIONS IN THIS FILE ARE INTERNAL WITH MUTABLE INTERFACES.  IT IS ONLY
     4     SAFE TO REACH THEM THROUGH DOCUMENTED INTERFACES.  IN FACT, IT IS ALMOST
     5     GUARANTEED THAT THEY'LL CHANGE OR DISAPPEAR IN A FUTURE GNU MP RELEASE.
     6  
     7  Copyright 1996, 1998, 2000-2004, 2008, 2011 Free Software Foundation, Inc.
     8  
     9  This file is part of the GNU MP Library.
    10  
    11  The GNU MP Library is free software; you can redistribute it and/or modify
    12  it under the terms of either:
    13  
    14    * the GNU Lesser General Public License as published by the Free
    15      Software Foundation; either version 3 of the License, or (at your
    16      option) any later version.
    17  
    18  or
    19  
    20    * the GNU General Public License as published by the Free Software
    21      Foundation; either version 2 of the License, or (at your option) any
    22      later version.
    23  
    24  or both in parallel, as here.
    25  
    26  The GNU MP Library is distributed in the hope that it will be useful, but
    27  WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
    28  or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    29  for more details.
    30  
    31  You should have received copies of the GNU General Public License and the
    32  GNU Lesser General Public License along with the GNU MP Library.  If not,
    33  see https://www.gnu.org/licenses/.  */
    34  
    35  #include "gmp.h"
    36  #include "gmp-impl.h"
    37  #include "longlong.h"
    38  
    39  #if GMP_NAIL_BITS > 0
    40  #error Nails not supported.
    41  #endif
    42  
    43  /* FIXME: Duplicated in hgcd2.c. Should move to gmp-impl.h, and
    44     possibly be renamed. */
    45  static inline mp_limb_t
    46  div1 (mp_ptr rp,
    47        mp_limb_t n0,
    48        mp_limb_t d0)
    49  {
    50    mp_limb_t q = 0;
    51  
    52    if ((mp_limb_signed_t) n0 < 0)
    53      {
    54        int cnt;
    55        for (cnt = 1; (mp_limb_signed_t) d0 >= 0; cnt++)
    56  	{
    57  	  d0 = d0 << 1;
    58  	}
    59  
    60        q = 0;
    61        while (cnt)
    62  	{
    63  	  q <<= 1;
    64  	  if (n0 >= d0)
    65  	    {
    66  	      n0 = n0 - d0;
    67  	      q |= 1;
    68  	    }
    69  	  d0 = d0 >> 1;
    70  	  cnt--;
    71  	}
    72      }
    73    else
    74      {
    75        int cnt;
    76        for (cnt = 0; n0 >= d0; cnt++)
    77  	{
    78  	  d0 = d0 << 1;
    79  	}
    80  
    81        q = 0;
    82        while (cnt)
    83  	{
    84  	  d0 = d0 >> 1;
    85  	  q <<= 1;
    86  	  if (n0 >= d0)
    87  	    {
    88  	      n0 = n0 - d0;
    89  	      q |= 1;
    90  	    }
    91  	  cnt--;
    92  	}
    93      }
    94    *rp = n0;
    95    return q;
    96  }
    97  
    98  /* Two-limb division optimized for small quotients.  */
    99  static inline mp_limb_t
   100  div2 (mp_ptr rp,
   101        mp_limb_t nh, mp_limb_t nl,
   102        mp_limb_t dh, mp_limb_t dl)
   103  {
   104    mp_limb_t q = 0;
   105  
   106    if ((mp_limb_signed_t) nh < 0)
   107      {
   108        int cnt;
   109        for (cnt = 1; (mp_limb_signed_t) dh >= 0; cnt++)
   110  	{
   111  	  dh = (dh << 1) | (dl >> (GMP_LIMB_BITS - 1));
   112  	  dl = dl << 1;
   113  	}
   114  
   115        while (cnt)
   116  	{
   117  	  q <<= 1;
   118  	  if (nh > dh || (nh == dh && nl >= dl))
   119  	    {
   120  	      sub_ddmmss (nh, nl, nh, nl, dh, dl);
   121  	      q |= 1;
   122  	    }
   123  	  dl = (dh << (GMP_LIMB_BITS - 1)) | (dl >> 1);
   124  	  dh = dh >> 1;
   125  	  cnt--;
   126  	}
   127      }
   128    else
   129      {
   130        int cnt;
   131        for (cnt = 0; nh > dh || (nh == dh && nl >= dl); cnt++)
   132  	{
   133  	  dh = (dh << 1) | (dl >> (GMP_LIMB_BITS - 1));
   134  	  dl = dl << 1;
   135  	}
   136  
   137        while (cnt)
   138  	{
   139  	  dl = (dh << (GMP_LIMB_BITS - 1)) | (dl >> 1);
   140  	  dh = dh >> 1;
   141  	  q <<= 1;
   142  	  if (nh > dh || (nh == dh && nl >= dl))
   143  	    {
   144  	      sub_ddmmss (nh, nl, nh, nl, dh, dl);
   145  	      q |= 1;
   146  	    }
   147  	  cnt--;
   148  	}
   149      }
   150  
   151    rp[0] = nl;
   152    rp[1] = nh;
   153  
   154    return q;
   155  }
   156  
   157  int
   158  mpn_hgcd2_jacobi (mp_limb_t ah, mp_limb_t al, mp_limb_t bh, mp_limb_t bl,
   159  		  struct hgcd_matrix1 *M, unsigned *bitsp)
   160  {
   161    mp_limb_t u00, u01, u10, u11;
   162    unsigned bits = *bitsp;
   163  
   164    if (ah < 2 || bh < 2)
   165      return 0;
   166  
   167    if (ah > bh || (ah == bh && al > bl))
   168      {
   169        sub_ddmmss (ah, al, ah, al, bh, bl);
   170        if (ah < 2)
   171  	return 0;
   172  
   173        u00 = u01 = u11 = 1;
   174        u10 = 0;
   175        bits = mpn_jacobi_update (bits, 1, 1);
   176      }
   177    else
   178      {
   179        sub_ddmmss (bh, bl, bh, bl, ah, al);
   180        if (bh < 2)
   181  	return 0;
   182  
   183        u00 = u10 = u11 = 1;
   184        u01 = 0;
   185        bits = mpn_jacobi_update (bits, 0, 1);
   186      }
   187  
   188    if (ah < bh)
   189      goto subtract_a;
   190  
   191    for (;;)
   192      {
   193        ASSERT (ah >= bh);
   194        if (ah == bh)
   195  	goto done;
   196  
   197        if (ah < (CNST_LIMB(1) << (GMP_LIMB_BITS / 2)))
   198  	{
   199  	  ah = (ah << (GMP_LIMB_BITS / 2) ) + (al >> (GMP_LIMB_BITS / 2));
   200  	  bh = (bh << (GMP_LIMB_BITS / 2) ) + (bl >> (GMP_LIMB_BITS / 2));
   201  
   202  	  break;
   203  	}
   204  
   205        /* Subtract a -= q b, and multiply M from the right by (1 q ; 0
   206  	 1), affecting the second column of M. */
   207        ASSERT (ah > bh);
   208        sub_ddmmss (ah, al, ah, al, bh, bl);
   209  
   210        if (ah < 2)
   211  	goto done;
   212  
   213        if (ah <= bh)
   214  	{
   215  	  /* Use q = 1 */
   216  	  u01 += u00;
   217  	  u11 += u10;
   218  	  bits = mpn_jacobi_update (bits, 1, 1);
   219  	}
   220        else
   221  	{
   222  	  mp_limb_t r[2];
   223  	  mp_limb_t q = div2 (r, ah, al, bh, bl);
   224  	  al = r[0]; ah = r[1];
   225  	  if (ah < 2)
   226  	    {
   227  	      /* A is too small, but q is correct. */
   228  	      u01 += q * u00;
   229  	      u11 += q * u10;
   230  	      bits = mpn_jacobi_update (bits, 1, q & 3);
   231  	      goto done;
   232  	    }
   233  	  q++;
   234  	  u01 += q * u00;
   235  	  u11 += q * u10;
   236  	  bits = mpn_jacobi_update (bits, 1, q & 3);
   237  	}
   238      subtract_a:
   239        ASSERT (bh >= ah);
   240        if (ah == bh)
   241  	goto done;
   242  
   243        if (bh < (CNST_LIMB(1) << (GMP_LIMB_BITS / 2)))
   244  	{
   245  	  ah = (ah << (GMP_LIMB_BITS / 2) ) + (al >> (GMP_LIMB_BITS / 2));
   246  	  bh = (bh << (GMP_LIMB_BITS / 2) ) + (bl >> (GMP_LIMB_BITS / 2));
   247  
   248  	  goto subtract_a1;
   249  	}
   250  
   251        /* Subtract b -= q a, and multiply M from the right by (1 0 ; q
   252  	 1), affecting the first column of M. */
   253        sub_ddmmss (bh, bl, bh, bl, ah, al);
   254  
   255        if (bh < 2)
   256  	goto done;
   257  
   258        if (bh <= ah)
   259  	{
   260  	  /* Use q = 1 */
   261  	  u00 += u01;
   262  	  u10 += u11;
   263  	  bits = mpn_jacobi_update (bits, 0, 1);
   264  	}
   265        else
   266  	{
   267  	  mp_limb_t r[2];
   268  	  mp_limb_t q = div2 (r, bh, bl, ah, al);
   269  	  bl = r[0]; bh = r[1];
   270  	  if (bh < 2)
   271  	    {
   272  	      /* B is too small, but q is correct. */
   273  	      u00 += q * u01;
   274  	      u10 += q * u11;
   275  	      bits = mpn_jacobi_update (bits, 0, q & 3);
   276  	      goto done;
   277  	    }
   278  	  q++;
   279  	  u00 += q * u01;
   280  	  u10 += q * u11;
   281  	  bits = mpn_jacobi_update (bits, 0, q & 3);
   282  	}
   283      }
   284  
   285    /* NOTE: Since we discard the least significant half limb, we don't
   286       get a truly maximal M (corresponding to |a - b| <
   287       2^{GMP_LIMB_BITS +1}). */
   288    /* Single precision loop */
   289    for (;;)
   290      {
   291        ASSERT (ah >= bh);
   292        if (ah == bh)
   293  	break;
   294  
   295        ah -= bh;
   296        if (ah < (CNST_LIMB (1) << (GMP_LIMB_BITS / 2 + 1)))
   297  	break;
   298  
   299        if (ah <= bh)
   300  	{
   301  	  /* Use q = 1 */
   302  	  u01 += u00;
   303  	  u11 += u10;
   304  	  bits = mpn_jacobi_update (bits, 1, 1);
   305  	}
   306        else
   307  	{
   308  	  mp_limb_t r;
   309  	  mp_limb_t q = div1 (&r, ah, bh);
   310  	  ah = r;
   311  	  if (ah < (CNST_LIMB(1) << (GMP_LIMB_BITS / 2 + 1)))
   312  	    {
   313  	      /* A is too small, but q is correct. */
   314  	      u01 += q * u00;
   315  	      u11 += q * u10;
   316  	      bits = mpn_jacobi_update (bits, 1, q & 3);
   317  	      break;
   318  	    }
   319  	  q++;
   320  	  u01 += q * u00;
   321  	  u11 += q * u10;
   322  	  bits = mpn_jacobi_update (bits, 1, q & 3);
   323  	}
   324      subtract_a1:
   325        ASSERT (bh >= ah);
   326        if (ah == bh)
   327  	break;
   328  
   329        bh -= ah;
   330        if (bh < (CNST_LIMB (1) << (GMP_LIMB_BITS / 2 + 1)))
   331  	break;
   332  
   333        if (bh <= ah)
   334  	{
   335  	  /* Use q = 1 */
   336  	  u00 += u01;
   337  	  u10 += u11;
   338  	  bits = mpn_jacobi_update (bits, 0, 1);
   339  	}
   340        else
   341  	{
   342  	  mp_limb_t r;
   343  	  mp_limb_t q = div1 (&r, bh, ah);
   344  	  bh = r;
   345  	  if (bh < (CNST_LIMB(1) << (GMP_LIMB_BITS / 2 + 1)))
   346  	    {
   347  	      /* B is too small, but q is correct. */
   348  	      u00 += q * u01;
   349  	      u10 += q * u11;
   350  	      bits = mpn_jacobi_update (bits, 0, q & 3);
   351  	      break;
   352  	    }
   353  	  q++;
   354  	  u00 += q * u01;
   355  	  u10 += q * u11;
   356  	  bits = mpn_jacobi_update (bits, 0, q & 3);
   357  	}
   358      }
   359  
   360   done:
   361    M->u[0][0] = u00; M->u[0][1] = u01;
   362    M->u[1][0] = u10; M->u[1][1] = u11;
   363    *bitsp = bits;
   364  
   365    return 1;
   366  }