Пример #1
0
        /** Do one the the 16 possible bit-wise operations of two IntNums. */
        public static void setBitOp(IntNum result, int op, IntNum x, IntNum y)
        {
            if (y.words == null)
            {
            }
            else if (x.words == null || x.ival < y.ival)
            {
                IntNum temp = x;  x = y;  y = temp;
                op = swappedOp(op);
            }
            int xi;
            int yi;
            int xlen, ylen;

            if (y.words == null)
            {
                yi   = y.ival;
                ylen = 1;
            }
            else
            {
                yi   = y.words[0];
                ylen = y.ival;
            }
            if (x.words == null)
            {
                xi   = x.ival;
                xlen = 1;
            }
            else
            {
                xi   = x.words[0];
                xlen = x.ival;
            }
            if (xlen > 1)
            {
                result.realloc(xlen);
            }
            int[] w = result.words;
            int   i = 0;
            // Code for how to handle the remainder of x.
            // 0:  Truncate to length of y.
            // 1:  Copy rest of x.
            // 2:  Invert rest of x.
            int finish = 0;
            int ni;

            switch (op)
            {
            case 0:      // clr
                ni = 0;
                break;

            case 1:     // and
                for (;;)
                {
                    ni = (int)((uint)xi & (uint)yi);
                    if (i + 1 >= ylen)
                    {
                        break;
                    }
                    w[i++] = ni;  xi = x.words[i];  yi = y.words[i];
                }
                if (yi < 0)
                {
                    finish = 1;
                }
                break;

            case 2:     // andc2
                for (;;)
                {
                    ni = (int)((uint)xi & ~(uint)yi);
                    if (i + 1 >= ylen)
                    {
                        break;
                    }
                    w[i++] = ni;  xi = x.words[i];  yi = y.words[i];
                }
                if (yi >= 0)
                {
                    finish = 1;
                }
                break;

            case 3:         // copy x
                ni     = xi;
                finish = 1; // Copy rest
                break;

            case 4:     // andc1
                for (;;)
                {
                    ni = (int)(~(uint)xi & (uint)yi);
                    if (i + 1 >= ylen)
                    {
                        break;
                    }
                    w[i++] = ni;  xi = x.words[i];  yi = y.words[i];
                }
                if (yi < 0)
                {
                    finish = 2;
                }
                break;

            case 5:     // copy y
                for (;;)
                {
                    ni = yi;
                    if (i + 1 >= ylen)
                    {
                        break;
                    }
                    w[i++] = ni;  xi = x.words[i];  yi = y.words[i];
                }
                break;

            case 6:      // xor
                for (;;)
                {
                    ni = (int)((uint)xi ^ (uint)yi);
                    if (i + 1 >= ylen)
                    {
                        break;
                    }
                    w[i++] = ni;  xi = x.words[i];  yi = y.words[i];
                }
                finish = yi < 0 ? 2 : 1;
                break;

            case 7:      // ior
                for (;;)
                {
                    ni = (int)((uint)xi | (uint)yi);
                    if (i + 1 >= ylen)
                    {
                        break;
                    }
                    w[i++] = ni;  xi = x.words[i];  yi = y.words[i];
                }
                if (yi >= 0)
                {
                    finish = 1;
                }
                break;

            case 8:      // nor
                for (;;)
                {
                    ni = (int)(~((uint)xi | (uint)yi));
                    if (i + 1 >= ylen)
                    {
                        break;
                    }
                    w[i++] = ni;  xi = x.words[i];  yi = y.words[i];
                }
                if (yi >= 0)
                {
                    finish = 2;
                }
                break;

            case 9:      // eqv [exclusive nor]
                for (;;)
                {
                    ni = (int)(~((uint)xi ^ (uint)yi));
                    if (i + 1 >= ylen)
                    {
                        break;
                    }
                    w[i++] = ni;  xi = x.words[i];  yi = y.words[i];
                }
                finish = yi >= 0 ? 2 : 1;
                break;

            case 10:      // c2
                for (;;)
                {
                    ni = (int)(~(uint)yi);
                    if (i + 1 >= ylen)
                    {
                        break;
                    }
                    w[i++] = ni;  xi = x.words[i];  yi = y.words[i];
                }
                break;

            case 11:      // orc2
                for (;;)
                {
                    ni = (int)((uint)xi | ~(uint)yi);
                    if (i + 1 >= ylen)
                    {
                        break;
                    }
                    w[i++] = ni;  xi = x.words[i];  yi = y.words[i];
                }
                if (yi < 0)
                {
                    finish = 1;
                }
                break;

            case 12:      // c1
                ni     = ~xi;
                finish = 2;
                break;

            case 13:      // orc1
                for (;;)
                {
                    ni = (int)(~(uint)xi | (uint)yi);
                    if (i + 1 >= ylen)
                    {
                        break;
                    }
                    w[i++] = ni;  xi = x.words[i];  yi = y.words[i];
                }
                if (yi >= 0)
                {
                    finish = 2;
                }
                break;

            case 14:      // nand
                for (;;)
                {
                    ni = (int)(~((uint)xi & (uint)yi));
                    if (i + 1 >= ylen)
                    {
                        break;
                    }
                    w[i++] = ni;  xi = x.words[i];  yi = y.words[i];
                }
                if (yi < 0)
                {
                    finish = 2;
                }
                break;

            default:
            case 15:      // set
                ni = -1;
                break;
            }
            // Here i==ylen-1; w[0]..w[i-1] have the correct result;
            // and ni contains the correct result for w[i+1].
            if (i + 1 == xlen)
            {
                finish = 0;
            }
            switch (finish)
            {
            case 0:
                if (i == 0 && w == null)
                {
                    result.ival = ni;
                    return;
                }
                w[i++] = ni;
                break;

            case 1:  w[i] = ni;  while (++i < xlen)
                {
                    w[i] = x.words[i];
                }
                break;

            case 2:  w[i] = ni;  while (++i < xlen)
                {
                    w[i] = ~x.words[i];
                }
                break;
            }
            result.ival = i;
        }
Пример #2
0
        /** Do one the the 16 possible bit-wise operations of two IntNums. */
        public static void setBitOp(IntNum result, int op, IntNum x, IntNum y)
        {
            if (y.words == null) {

            } else if (x.words == null || x.ival < y.ival)
                {
                    IntNum temp = x;  x = y;  y = temp;
                    op = swappedOp (op);
                }
            int xi;
            int yi;
            int xlen, ylen;
            if (y.words == null)
                {
                    yi = y.ival;
                    ylen = 1;
                }
            else
                {
                    yi = y.words[0];
                    ylen = y.ival;
                }
            if (x.words == null)
                {
                    xi = x.ival;
                    xlen = 1;
                }
            else
                {
                    xi = x.words[0];
                    xlen = x.ival;
                }
            if (xlen > 1)
                result.realloc (xlen);
            int[] w = result.words;
            int i = 0;
            // Code for how to handle the remainder of x.
            // 0:  Truncate to length of y.
            // 1:  Copy rest of x.
            // 2:  Invert rest of x.
            int finish = 0;
            int ni;
            switch (op)
                {
                case 0:  // clr
                    ni = 0;
                    break;
                case 1: // and
                    for (;;)
                        {
                            ni = (int)((uint)xi & (uint)yi);
                            if (i+1 >= ylen) break;
                            w[i++] = ni;  xi = x.words[i];  yi = y.words[i];
                        }
                    if (yi < 0) finish = 1;
                    break;
                case 2: // andc2
                    for (;;)
                        {
                            ni = (int)((uint)xi & ~(uint)yi);
                            if (i+1 >= ylen) break;
                            w[i++] = ni;  xi = x.words[i];  yi = y.words[i];
                        }
                    if (yi >= 0) finish = 1;
                    break;
                case 3:  // copy x
                    ni = xi;
                    finish = 1;  // Copy rest
                    break;
                case 4: // andc1
                    for (;;)
                        {
                            ni = (int)(~(uint)xi & (uint)yi);
                            if (i+1 >= ylen) break;
                            w[i++] = ni;  xi = x.words[i];  yi = y.words[i];
                        }
                    if (yi < 0) finish = 2;
                    break;
                case 5: // copy y
                    for (;;)
                        {
                            ni = yi;
                            if (i+1 >= ylen) break;
                            w[i++] = ni;  xi = x.words[i];  yi = y.words[i];
                        }
                    break;
                case 6:  // xor
                    for (;;)
                        {
                            ni = (int)((uint)xi ^ (uint)yi);
                            if (i+1 >= ylen) break;
                            w[i++] = ni;  xi = x.words[i];  yi = y.words[i];
                        }
                    finish = yi < 0 ? 2 : 1;
                    break;
                case 7:  // ior
                    for (;;)
                        {
                            ni = (int)((uint)xi | (uint)yi);
                            if (i+1 >= ylen) break;
                            w[i++] = ni;  xi = x.words[i];  yi = y.words[i];
                        }
                    if (yi >= 0) finish = 1;
                    break;
                case 8:  // nor
                    for (;;)
                        {
                            ni = (int)(~((uint)xi | (uint)yi));
                            if (i+1 >= ylen) break;
                            w[i++] = ni;  xi = x.words[i];  yi = y.words[i];
                        }
                    if (yi >= 0)  finish = 2;
                    break;
                case 9:  // eqv [exclusive nor]
                    for (;;)
                        {
                            ni = (int)(~((uint)xi ^ (uint)yi));
                            if (i+1 >= ylen) break;
                            w[i++] = ni;  xi = x.words[i];  yi = y.words[i];
                        }
                    finish = yi >= 0 ? 2 : 1;
                    break;
                case 10:  // c2
                    for (;;)
                        {
                            ni = (int)(~(uint)yi);
                            if (i+1 >= ylen) break;
                            w[i++] = ni;  xi = x.words[i];  yi = y.words[i];
                        }
                    break;
                case 11:  // orc2
                    for (;;)
                        {
                            ni = (int)((uint)xi | ~(uint)yi);
                            if (i+1 >= ylen) break;
                            w[i++] = ni;  xi = x.words[i];  yi = y.words[i];
                        }
                    if (yi < 0)  finish = 1;
                    break;
                case 12:  // c1
                    ni = ~xi;
                    finish = 2;
                    break;
                case 13:  // orc1
                    for (;;)
                        {
                            ni = (int)(~(uint)xi | (uint)yi);
                            if (i+1 >= ylen) break;
                            w[i++] = ni;  xi = x.words[i];  yi = y.words[i];
                        }
                    if (yi >= 0) finish = 2;
                    break;
                case 14:  // nand
                    for (;;)
                        {
                            ni = (int)(~((uint)xi & (uint)yi));
                            if (i+1 >= ylen) break;
                            w[i++] = ni;  xi = x.words[i];  yi = y.words[i];
                        }
                    if (yi < 0) finish = 2;
                    break;
                default:
                case 15:  // set
                    ni = -1;
                    break;
                }
            // Here i==ylen-1; w[0]..w[i-1] have the correct result;
            // and ni contains the correct result for w[i+1].
            if (i+1 == xlen)
                finish = 0;
            switch (finish)
                {
                case 0:
                    if (i == 0 && w == null)
                        {
                            result.ival = ni;
                            return;
                        }
                    w[i++] = ni;
                    break;
                case 1:  w[i] = ni;  while (++i < xlen)  w[i] = x.words[i];  break;
                case 2:  w[i] = ni;  while (++i < xlen)  w[i] = ~x.words[i];  break;
                }
            result.ival = i;
        }