Example #1
0
        /// <include file='../../docs.xml'
        /// path='docs/doc[@name="M:PeterO.Numbers.FastInteger.Negate"]/*'/>
        internal FastInteger Negate()
        {
            this.CheckFrozen();
            switch (this.integerMode)
            {
            case 0:
                if (this.smallValue == Int32.MinValue)
                {
                    // would overflow, convert to large
                    this.integerMode = 1;
                    this.mnum        =
                        MutableNumber.FromEInteger(ValueNegativeInt32MinValue);
                }
                else
                {
                    smallValue = -smallValue;
                }
                break;

            case 1:
                this.integerMode = 2;
                this.largeValue  = this.mnum.ToEInteger();
                this.largeValue  = -(EInteger)this.largeValue;
                break;

            case 2:
                this.largeValue = -(EInteger)this.largeValue;
                break;

            default:
                throw new InvalidOperationException();
            }
            return(this);
        }
Example #2
0
            public int CompareTo(MutableNumber other)
            {
                if (this.wordCount != other.wordCount)
                {
                    return((this.wordCount < other.wordCount) ? -1 : 1);
                }
                int valueN = this.wordCount;

                while (unchecked (valueN--) != 0)
                {
                    int an = this.data[valueN];
                    int bn = other.data[valueN];
                    // Unsigned less-than check
                    if (((an >> 31) == (bn >> 31)) ?
                        ((an & Int32.MaxValue) < (bn & Int32.MaxValue)) :
                        ((an >> 31) == 0))
                    {
                        return(-1);
                    }
                    if (an != bn)
                    {
                        return(1);
                    }
                }
                return(0);
            }
Example #3
0
        internal FastInteger AddInt(int val)
        {
            this.CheckFrozen();
            EInteger valValue;

            switch (this.integerMode)
            {
            case 0:
                if ((this.smallValue < 0 && (int)val < Int32.MinValue -
                     this.smallValue) || (this.smallValue > 0 && (int)val >
                                          Int32.MaxValue - this.smallValue))
                {
                    // would overflow
                    if (val >= 0)
                    {
                        this.integerMode = 1;
                        this.mnum        = new MutableNumber(this.smallValue);
                        this.mnum.Add(val);
                    }
                    else
                    {
                        this.integerMode = 2;
                        this.largeValue  = (EInteger)this.smallValue;
                        this.largeValue += (EInteger)val;
                    }
                }
                else
                {
                    smallValue += val;
                }
                break;

            case 1:
                if (val >= 0)
                {
                    this.mnum.Add(val);
                }
                else
                {
                    integerMode = 2;
                    largeValue  = mnum.ToEInteger();
                    valValue    = (EInteger)val;
                    largeValue += (EInteger)valValue;
                }
                break;

            case 2:
                valValue         = (EInteger)val;
                this.largeValue += (EInteger)valValue;
                break;

            default: throw new InvalidOperationException();
            }
            return(this);
        }
Example #4
0
            internal MutableNumber Copy()
            {
                var mbi = new MutableNumber(0);

                if (this.wordCount > mbi.data.Length)
                {
                    mbi.data = new int[this.wordCount];
                }
                Array.Copy(this.data, mbi.data, this.wordCount);
                mbi.wordCount = this.wordCount;
                return(mbi);
            }
Example #5
0
        internal FastInteger Divide(int divisor)
        {
            this.CheckFrozen();
            if (divisor != 0)
            {
                switch (this.integerMode)
                {
                case 0:
                    if (divisor == -1 && this.smallValue == Int32.MinValue)
                    {
                        // would overflow, convert to large
                        this.integerMode = 1;
                        this.mnum        =
                            MutableNumber.FromEInteger(ValueNegativeInt32MinValue);
                    }
                    else
                    {
                        smallValue /= divisor;
                    }
                    break;

                case 1:
                    this.integerMode = 2;
                    this.largeValue  = this.mnum.ToEInteger();
                    this.largeValue /= (EInteger)divisor;
                    if (this.largeValue.IsZero)
                    {
                        this.integerMode = 0;
                        this.smallValue  = 0;
                    }
                    break;

                case 2:
                    this.largeValue /= (EInteger)divisor;
                    if (this.largeValue.IsZero)
                    {
                        this.integerMode = 0;
                        this.smallValue  = 0;
                    }
                    break;

                default:
                    throw new InvalidOperationException();
                }
            }
            else
            {
                throw new DivideByZeroException();
            }
            return(this);
        }
Example #6
0
 internal MutableNumber Subtract(MutableNumber other)
 {
     unchecked {
         {
             // Console.WriteLine("" + this.data.Length + " " +
             // (other.data.Length));
             int neededSize = (this.wordCount > other.wordCount) ?
                              this.wordCount : other.wordCount;
             if (this.data.Length < neededSize)
             {
                 var newdata = new int[neededSize + 20];
                 Array.Copy(this.data, 0, newdata, 0, this.data.Length);
                 this.data = newdata;
             }
             neededSize = (this.wordCount < other.wordCount) ? this.wordCount :
                          other.wordCount;
             var u      = 0;
             var borrow = 0;
             for (var i = 0; i < neededSize; ++i)
             {
                 int a = this.data[i];
                 u      = (a - other.data[i]) - borrow;
                 borrow = ((((a >> 31) == (u >> 31)) ? ((a & Int32.MaxValue) <
                                                        (u & Int32.MaxValue)) :
                            ((a >> 31) == 0)) || (a == u && other.data[i] !=
                                                  0)) ? 1 : 0;
                 this.data[i] = (int)u;
             }
             if (borrow != 0)
             {
                 for (int i = neededSize; i < this.wordCount; ++i)
                 {
                     int a = this.data[i];
                     u      = (a - other.data[i]) - borrow;
                     borrow = ((((a >> 31) == (u >> 31)) ? ((a & Int32.MaxValue) <
                                                            (u & Int32.MaxValue)) :
                                ((a >> 31) == 0)) || (a == u && other.data[i] !=
                                                      0)) ? 1 : 0;
                     this.data[i] = (int)u;
                 }
             }
             // Calculate the correct data length
             while (this.wordCount != 0 && this.data[this.wordCount - 1] == 0)
             {
                 --this.wordCount;
             }
             return(this);
         }
     }
 }
Example #7
0
 internal FastInteger Increment()
 {
     this.CheckFrozen();
     if (this.integerMode == 0)
     {
         if (this.smallValue != Int32.MaxValue)
         {
             ++this.smallValue;
         }
         else
         {
             this.integerMode = 1;
             this.mnum        = MutableNumber.FromEInteger(ValueNegativeInt32MinValue);
         }
         return(this);
     }
     return(this.AddInt(1));
 }
Example #8
0
            internal static MutableNumber FromEInteger(EInteger bigintVal)
            {
                var mnum = new MutableNumber(0);

                if (bigintVal.Sign < 0)
                {
                    throw new ArgumentException("bigintVal's sign (" + bigintVal.Sign +
                                                ") is less than " + "0 ");
                }
                byte[] bytes        = bigintVal.ToBytes(true);
                int    len          = bytes.Length;
                int    newWordCount = Math.Max(4, (len / 4) + 1);

                if (newWordCount > mnum.data.Length)
                {
                    mnum.data = new int[newWordCount];
                }
                mnum.wordCount = newWordCount;
                unchecked {
                    for (var i = 0; i < len; i += 4)
                    {
                        int x = ((int)bytes[i]) & 0xff;
                        if (i + 1 < len)
                        {
                            x |= (((int)bytes[i + 1]) & 0xff) << 8;
                        }
                        if (i + 2 < len)
                        {
                            x |= (((int)bytes[i + 2]) & 0xff) << 16;
                        }
                        if (i + 3 < len)
                        {
                            x |= (((int)bytes[i + 3]) & 0xff) << 24;
                        }
                        mnum.data[i >> 2] = x;
                    }
                }
                // Calculate the correct data length
                while (mnum.wordCount != 0 && mnum.data[mnum.wordCount - 1] == 0)
                {
                    --mnum.wordCount;
                }
                return(mnum);
            }
Example #9
0
            public static MutableNumber FromLong(long longVal)
            {
                if (longVal < 0)
                {
                    throw new ArgumentException();
                }
                if (longVal == 0)
                {
                    return(new MutableNumber(0));
                }
                var mbi = new MutableNumber(0);

                mbi.data[0] = unchecked ((int)longVal);
                int mbd = unchecked ((int)(longVal >> 32));

                mbi.data[1]   = mbd;
                mbi.wordCount = (mbd == 0) ? 1 : 2;
                return(mbi);
            }
Example #10
0
 internal FastInteger Decrement()
 {
     this.CheckFrozen();
     if (this.integerMode == 0)
     {
         if (this.smallValue != Int32.MinValue)
         {
             --this.smallValue;
         }
         else
         {
             this.integerMode = 1;
             this.mnum        = MutableNumber.FromEInteger(ValueInt32MinValue);
             this.mnum.SubtractInt(1);
         }
         return(this);
     }
     return(this.SubtractInt(1));
 }
Example #11
0
 internal static FastInteger FromBig(EInteger bigintVal)
 {
     if (bigintVal.CanFitInInt32())
     {
         return(new FastInteger(bigintVal.ToInt32Unchecked()));
     }
     if (bigintVal.Sign > 0)
     {
         var fi = new FastInteger(0);
         fi.integerMode = 1;
         fi.mnum        = MutableNumber.FromEInteger(bigintVal);
         return(fi);
     }
     else
     {
         var fi = new FastInteger(0);
         fi.integerMode = 2;
         fi.largeValue  = bigintVal;
         return(fi);
     }
 }
Example #12
0
 internal FastInteger2 Add(FastInteger2 val)
 {
     EInteger valValue;
       switch (this.integerMode) {
     case 0:
       if (val.integerMode == 0) {
     if ((this.smallValue < 0 && (int)val.smallValue < Int32.MinValue
     - this.smallValue) ||
         (this.smallValue > 0 && (int)val.smallValue > Int32.MaxValue
         - this.smallValue)) {
       // would overflow
       if (val.smallValue >= 0) {
         this.integerMode = 1;
         this.mnum = new MutableNumber(this.smallValue);
         this.mnum.Add(val.smallValue);
       } else {
         this.integerMode = 2;
         this.largeValue = (EInteger)this.smallValue;
         this.largeValue += (EInteger)val.smallValue;
       }
     } else {
       this.smallValue += val.smallValue;
     }
       } else {
     integerMode = 2;
     largeValue = (EInteger)smallValue;
     valValue = val.AsBigInteger();
     largeValue += (EInteger)valValue;
       }
       break;
     case 1:
       if (val.integerMode == 0 && val.smallValue >= 0) {
     this.mnum.Add(val.smallValue);
       } else {
     integerMode = 2;
     largeValue = mnum.ToEInteger();
     valValue = val.AsBigInteger();
     largeValue += (EInteger)valValue;
       }
       break;
     case 2:
       valValue = val.AsBigInteger();
       this.largeValue += (EInteger)valValue;
       break;
     default: throw new InvalidOperationException();
       }
       return this;
 }
Example #13
0
 internal MutableNumber Subtract(MutableNumber other)
 {
     unchecked {
       {
        // Console.WriteLine("" + this.data.Length + " " +
      // (other.data.Length));
     int neededSize = (this.wordCount > other.wordCount) ?
     this.wordCount : other.wordCount;
     if (this.data.Length < neededSize) {
       var newdata = new int[neededSize + 20];
       Array.Copy(this.data, 0, newdata, 0, this.data.Length);
       this.data = newdata;
     }
     neededSize = (this.wordCount < other.wordCount) ? this.wordCount :
     other.wordCount;
     var u = 0;
     var borrow = 0;
     for (var i = 0; i < neededSize; ++i) {
       int a = this.data[i];
       u = (a - other.data[i]) - borrow;
       borrow = ((((a >> 31) == (u >> 31)) ? ((a & Int32.MaxValue) <
       (u & Int32.MaxValue)) :
         ((a >> 31) == 0)) || (a == u && other.data[i] !=
         0)) ? 1 : 0;
       this.data[i] = (int)u;
     }
     if (borrow != 0) {
       for (int i = neededSize; i < this.wordCount; ++i) {
     int a = this.data[i];
     u = (a - other.data[i]) - borrow;
     borrow = ((((a >> 31) == (u >> 31)) ? ((a & Int32.MaxValue) <
     (u & Int32.MaxValue)) :
         ((a >> 31) == 0)) || (a == u && other.data[i] !=
         0)) ? 1 : 0;
     this.data[i] = (int)u;
       }
     }
     // Calculate the correct data length
     while (this.wordCount != 0 && this.data[this.wordCount - 1] == 0) {
       --this.wordCount;
     }
     return this;
       }
     }
 }
Example #14
0
 /// <include file='../../docs.xml'
 /// path='docs/doc[@name="M:PeterO.Cbor.FastInteger2.Multiply(System.Int32)"]/*'/>
 internal FastInteger2 Multiply(int val)
 {
     if (val == 0) {
     this.smallValue = 0;
     this.integerMode = 0;
       } else {
     switch (this.integerMode) {
       case 0:
     bool apos = this.smallValue > 0L;
     bool bpos = val > 0L;
     if (
       (apos && ((!bpos && (Int32.MinValue / this.smallValue) > val) ||
             (bpos && this.smallValue > (Int32.MaxValue / val)))) ||
       (!apos && ((!bpos && this.smallValue != 0L &&
             (Int32.MaxValue / this.smallValue) > val) ||
             (bpos && this.smallValue < (Int32.MinValue / val))))) {
       // would overflow, convert to large
       if (apos && bpos) {
         // if both operands are nonnegative
         // convert to mutable big integer
         this.integerMode = 1;
         this.mnum = new MutableNumber(this.smallValue);
         this.mnum.Multiply(val);
       } else {
         // if either operand is negative
         // convert to big integer
         this.integerMode = 2;
         this.largeValue = (EInteger)this.smallValue;
         this.largeValue *= (EInteger)val;
       }
     } else {
       smallValue *= val;
     }
     break;
       case 1:
     if (val < 0) {
       this.integerMode = 2;
       this.largeValue = this.mnum.ToEInteger();
       this.largeValue *= (EInteger)val;
     } else {
       mnum.Multiply(val);
     }
     break;
       case 2:
     this.largeValue *= (EInteger)val;
     break;
       default: throw new InvalidOperationException();
     }
       }
       return this;
 }
Example #15
0
        /// <include file='../../docs.xml'
        /// path='docs/doc[@name="M:PeterO.Numbers.FastInteger.Multiply(System.Int32)"]/*'/>
        internal FastInteger Multiply(int val)
        {
            this.CheckFrozen();
            if (val == 0)
            {
                this.smallValue  = 0;
                this.integerMode = 0;
            }
            else
            {
                switch (this.integerMode)
                {
                case 0: {
                    long amult = ((long)val) * ((long)this.smallValue);
                    if (amult > Int32.MaxValue || amult < Int32.MinValue)
                    {
                        // would overflow, convert to large
                        bool apos = this.smallValue > 0L;
                        bool bpos = val > 0L;
                        if (apos && bpos)
                        {
                            // if both operands are nonnegative
                            // convert to mutable big integer
                            this.integerMode = 1;
                            this.mnum        = MutableNumber.FromLong(amult);
                        }
                        else
                        {
                            // if either operand is negative
                            // convert to big integer
                            this.integerMode = 2;
                            this.largeValue  = EInteger.FromInt64(amult);
                        }
                    }
                    else
                    {
                        this.smallValue = unchecked ((int)amult);
                    }
                    break;
                }

                case 1:
                    if (val < 0)
                    {
                        this.integerMode = 2;
                        this.largeValue  = this.mnum.ToEInteger();
                        this.largeValue *= (EInteger)val;
                    }
                    else
                    {
                        mnum.Multiply(val);
                    }
                    break;

                case 2:
                    this.largeValue *= (EInteger)val;
                    break;

                default: throw new InvalidOperationException();
                }
            }
            return(this);
        }
Example #16
0
 internal static int[] GetLastWords(EInteger bigint, int numWords32Bit)
 {
     return
         (MutableNumber.FromEInteger(bigint).GetLastWordsInternal(numWords32Bit));
 }