Microsoft.Scripting.Math.BigInteger.DivModUnsigned C# (CSharp) Méthode

DivModUnsigned() private static méthode

private static DivModUnsigned ( uint u, uint v, uint &q, uint &r ) : void
u uint
v uint
q uint
r uint
Résultat void
    private static void DivModUnsigned(uint[] u, uint[] v, out uint[] q, out uint[] r) {
      int m = GetLength(u);
      int n = GetLength(v);

      if (n <= 1) {
        if (n == 0) {
          throw new DivideByZeroException();
        }

        //  Divide by single digit
        //
        ulong rem = 0;
        uint v0 = v[0];
        q = new uint[m];
        r = new uint[1];

        for (int j = m - 1; j >= 0; j--) {
          rem *= Base;
          rem += u[j];

          ulong div = rem / v0;
          rem -= div * v0;
          q[j] = (uint)div;
        }
        r[0] = (uint)rem;
      } else if (m >= n) {
        int shift = GetNormalizeShift(v[n - 1]);

        uint[] un = new uint[m + 1];
        uint[] vn = new uint[n];

        Normalize(u, m, un, shift);
        Normalize(v, n, vn, shift);

        q = new uint[m - n + 1];
        r = null;

        TestDivisionStep(un, vn, q, u, v);

        //  Main division loop
        //
        for (int j = m - n; j >= 0; j--) {
          ulong rr, qq;
          int i;

          rr = Base * un[j + n] + un[j + n - 1];
          qq = rr / vn[n - 1];
          rr -= qq * vn[n - 1];

          Debug.Assert((Base * un[j + n] + un[j + n - 1]) == qq * vn[n - 1] + rr);

          for (; ; ) {
            // Estimate too big ?
            //
            if ((qq >= Base) || (qq * vn[n - 2] > (rr * Base + un[j + n - 2]))) {
              qq--;
              rr += (ulong)vn[n - 1];
              if (rr < Base) continue;
            }
            break;
          }

          Debug.Assert((Base * un[j + n] + un[j + n - 1]) == qq * vn[n - 1] + rr);

          //  Multiply and subtract
          //
          long b = 0;
          long t = 0;
          for (i = 0; i < n; i++) {
            ulong p = vn[i] * qq;
            t = (long)un[i + j] - (long)(uint)p - b;
            un[i + j] = (uint)t;
            p >>= 32;
            t >>= 32;
            Debug.Assert(t == 0 || t == -1 || t == -2);
            b = (long)p - t;
          }
          t = (long)un[j + n] - b;
          un[j + n] = (uint)t;

          //  Store the calculated value
          //
          q[j] = (uint)qq;

          //  Add back vn[0..n] to un[j..j+n]
          //
          if (t < 0) {
            q[j]--;
            ulong c = 0;
            for (i = 0; i < n; i++) {
              c = (ulong)vn[i] + un[j + i] + c;
              un[j + i] = (uint)c;
              c >>= 32;
            }
            c += (ulong)un[j + n];
            un[j + n] = (uint)c;
          }

          TestDivisionStep(un, vn, q, u, v);
        }

        Unnormalize(un, out r, shift);

        //  Test normalized value ... Call TestNormalize
        //  only pass the values in different order.
        //
        TestNormalize(r, un, shift);
      } else {
        q = new uint[] { 0 };
        r = u;
      }

      TestResult(u, v, q, r);
    }