Ejemplo n.º 1
0
        public override int Compare(CNumber other)
        {
            if (other.MyType != MyType)
            {
                throw new NotImplementedException();
            }

            CNumber_Integer o = (CNumber_Integer)other;

            int t_len = size;
            int o_len = o.size;

            if (o_len > t_len)
            {
                return(-1);
            }
            if (o_len < t_len)
            {
                return(1);
            }

            --t_len;
            while (t_len > 0 && o._Values[t_len] == _Values[t_len])
            {
                --t_len;
            }
            return(Math.Sign(_Values[t_len] - o._Values[t_len]));
        }
Ejemplo n.º 2
0
        //------------------------------------------------------------
        // add a number
        // the native way to take care of the overflow
        // is checking after the summation if the sum is less than
        // one of the summands, this would mean overflow
        // but this would need some more conditional branches
        // so I choose a way with conversions from uint to ulong
        // to let the .Net calc the overflow
        protected virtual void Addition(CNumber_Integer other)
        {
            ulong rem   = 0;                                // the remainder (either 0 or 1) (ulong for the overflow)
            int   o_len = other._Values.Count;              // the other length
            int   t_len = _Values.Count;                    // our own length
            int   len   = (t_len < o_len) ? t_len : o_len;  // calc the minimum length
            int   i     = 0;                                // start with the lowest digit

            for (; i < len; i++)                            // first add all common digits
            {
                rem       += (ulong)other._Values[i];       // val = rem + val + other.val
                rem       += (ulong)_Values[i];
                _Values[i] = (uint)rem;
                rem      >>= 32;                            // rem = overflow
            }
            for (; i < o_len; i++)                          // now copy the remaining from the other
            {
                rem += (ulong)other._Values[i];             // don't forget the remainder
                _Values.Add((uint)rem);
                rem >>= 32;
            }
            for (; (rem > 0) && (i < t_len); i++)           // now increase our own remaining digits
            {                                               // as long as the remainder is non-zero
                rem       += (ulong)_Values[i];
                _Values[i] = (uint)rem;
                rem      >>= 32;
            }
            if (rem > 0)
            {
                _Values.Add((uint)rem);                     // still something left, just add it
            }
        }
Ejemplo n.º 3
0
        public override MMC.Numbers.CNumber sqr()
        {
            int cnt = _Values.Count;

            // calc the different interims (could be done in parallel)
            CNumber_Integer[] Results = new CNumber_Integer[cnt];
            for (int i = 0; i < cnt; ++i)
            {
                CNumber_Integer tmp = new CNumber_Integer(this);
                tmp.Multiply(_Values[i]);
                tmp._Values.InsertRange(0, new byte[i]);
                Results[i] = tmp;
            }

            // now add them all up
            CNumber_Integer res = new CNumber_Integer(Results[0]);

            for (int i = 1; i < cnt; i++)
            {
                res.Addition(Results[i]);
            }

            res.Trim();
            return(res);
        }
Ejemplo n.º 4
0
        //------------------------------------------------------------
        // convert into a string
        public override string ToString(uint Base)
        {
            // first the sign
            string str = (_Sign) ? "-" : "";

            // numbers of digits separated by '.'
            int step = 4;

            // now the base-indication
            switch (Base)
            {
            case 2: str += "0b"; break;

            case 8: str += "0o"; break;

            case 10: step = 3;  break;

            case 16: str += "0x"; break;

            default: str += '[' + Base.ToString() + ']'; break;
            }

            // if the base is a power of 2
            // let's calc the binary logarithm
            bool poweroftwo = ((Base & (Base - 1)) == 0);

            if (poweroftwo)
            {
                uint b = Base;
                Base = 0;
                while (b > 1)
                {
                    b >>= 1; Base++;
                }
                ;
            }

            // generate reversed string of digits
            CNumber_Integer tmp = (CNumber_Integer)Clone();
            string          num = String.Empty;
            int             cnt = 0;

            do
            {
                if (cnt == step)
                {
                    cnt = 0; num += '.';
                }
                uint rem = (poweroftwo) ? tmp.ShiftRight((int)Base) : tmp.Divide(Base);
                num += (char)((rem > 9) ? (rem - 10 + 'A') : (rem + '0'));
                cnt++;
            } while (!tmp.IsZero);

            for (int i = num.Length - 1; i >= 0; i--)
            {
                str += num[i];
            }
            return(str);
        }
Ejemplo n.º 5
0
        //------------------------------------------------------------
        // logical functions
        public override CNumber not()
        {
            CNumber_Integer res = new CNumber_Integer(this);

            res.Not();
            res.Trim();
            return(res);
        }
Ejemplo n.º 6
0
        //------------------------------------------------------------
        // return a negative version of this one
        public override MMC.Numbers.CNumber neg()
        {
            CNumber_Integer res = new CNumber_Integer(this);

            if (!IsZero)
            {
                res._Sign = !_Sign;
            }
            return(res);
        }
Ejemplo n.º 7
0
 //------------------------------------------------------------
 public CNumber_Integer(CNumber_Integer other)
 {
     if (other == null)
     {
         setZero();
     }
     else
     {
         CopyFrom(other);
     }
 }
Ejemplo n.º 8
0
        public override MMC.Numbers.CNumber rem(MMC.Numbers.CNumber other)
        {
            if (other.MyType != MyType)
            {
                throw new NotImplementedException();
            }

            CNumber_Integer Res = new CNumber_Integer(this);

            return(Res.Divide((CNumber_Integer)other));
        }
Ejemplo n.º 9
0
        //------------------------------------------------------------
        // helper to create a new number
        public MMC.Numbers.CNumber NewNumber(double Value)
        {
            MMC.Numbers.CNumber res = null;
            switch (_NumberType)
            {
            case MMC.Numbers.CNumber.CNumberType.cnt_Double:
                res = new MMC.Numbers.CNumber_Double(Value);
                break;

            case MMC.Numbers.CNumber.CNumberType.cnt_Integer:
                res = new MMC.Numbers.CNumber_Integer(Value);
                break;

            default:
                break;
            }
            return(res);
        }
Ejemplo n.º 10
0
        public override MMC.Numbers.CNumber sub(MMC.Numbers.CNumber other)
        {
            if (other.MyType != MyType)
            {
                throw new NotImplementedException();
            }
            CNumber_Integer res = new CNumber_Integer(this);

            if (_Sign != ((CNumber_Integer)other)._Sign)
            {
                res.Addition((CNumber_Integer)other);
            }
            else
            {
                res.Subtraction((CNumber_Integer)other);
            }
            return(res);
        }
Ejemplo n.º 11
0
        //------------------------------------------------------------
        // subtract a number of shorter or equal length
        protected virtual void Subtraction(CNumber_Integer other)
        {
            bool rem   = false;                             // the overflow state
            int  o_len = other._Values.Count;               // the other length
            int  t_len = _Values.Count;                     // our own length
            int  len   = (t_len < o_len) ? t_len : o_len;   // calc the minimum length
            int  i     = 0;                                 // start with the lowest digit

            for (; i < len; i++)
            {
                byte v = other._Values[i]; if (rem)
                {
                    ++v;
                }
                rem         = (v > _Values[i]);
                _Values[i] -= v;
            }
            for (; i < o_len; i++)                          // now copy the remaining from the other
            {
                byte v = other._Values[i]; if (rem)
                {
                    ++v;
                }
                _Values.Add((byte)(-v));                    // = 0-v;
                rem = true;                                 // allways an overflow
            }

            for (; rem && (i < t_len); ++i)                 // now decrease our own remaining digits
            {
                rem = (_Values[i] == 0);
                --_Values[i];
            }

            if (rem)                                        // if we have an overflow we have to
            {                                               // negate the result
                _Values[0] = (byte)(-_Values[0]);
                for (int k = 1; k < _Values.Count; k++)
                {
                    _Values[k] ^= 0xFF;
                }
                _Sign = !_Sign;
            }
            Trim();                                         // could have created some leading zeros
        }
Ejemplo n.º 12
0
        //------------------------------------------------------------
        // divide by another number and return the remainder
        protected virtual CNumber_Integer Divide(CNumber_Integer other)
        {
            CNumber_Integer Save = new CNumber_Integer(this);       // save the old value

            setZero();                                              // set the initial result to 0

            int o_len = other._Values.Count;
            int t_len = _Values.Count;
            int pos   = t_len - o_len;

            if (pos < 0)
            {
                return(Save);                                       // fewer digits means the result is zero and the remainder are just we
            }
            CNumber_Integer Rem = new CNumber_Integer();            // set the remainder to 0
            int             len = o_len - 1;

            while (pos >= 0)
            {
                Rem.InsertDigit(Save._Values[pos]);                 // take the next digit

                byte q = Rem._Values[len];
                q /= other._Values[len];                            // and make an estimate for the quotient

                CNumber_Integer tmp = new CNumber_Integer(other);   // and calculate the product for this estimated value
                tmp._Sign = false;
                tmp.Multiply(q);
                Rem.Subtraction(tmp);                               // see how good we estimated
                if (Rem._Sign)                                      // if we are too low just correct by one
                {
                    --q;
                    Rem.add(other);
                }

                InsertDigit(q);                                     // and write down the quotients digit
                --pos;                                              // walk one further in our (this) digits
            }

            _Sign = (_Sign != other._Sign);
            Trim();
            return(Rem);
        }
Ejemplo n.º 13
0
        public override CNumber xor(CNumber other)
        {
            if (other.MyType != MyType)
            {
                throw new NotImplementedException();
            }
            CNumber_Integer res   = new CNumber_Integer(this);
            CNumber_Integer o     = (CNumber_Integer)other;
            int             o_len = o._Values.Count;                 // the other length
            int             t_len = _Values.Count;                   // our own length
            int             len   = (t_len < o_len) ? t_len : o_len; // calc the minimum length
            int             i     = 0;                               // start with the lowest digit

            for (; i < len; i++)                                     // first handle the common digits
            {
                res._Values[i] ^= o._Values[i];
            }
            res.Trim();
            return(res);
        }
Ejemplo n.º 14
0
        // written multiplication
        public override MMC.Numbers.CNumber mul(MMC.Numbers.CNumber other)
        {
            if (other.MyType != MyType)
            {
                throw new NotImplementedException();
            }

            CNumber_Integer o   = (CNumber_Integer)other;
            int             cnt = o._Values.Count;

            // calc the different interims (could be done in parallel)
            CNumber_Integer[] Results = new CNumber_Integer[cnt];
            for (int i = 0; i < cnt; i++)
            {
                CNumber_Integer tmp = new CNumber_Integer(this);
                tmp.Multiply(o._Values[i]);
                tmp._Values.InsertRange(0, new byte[i]);
                Results[i] = tmp;
            }

            // now add them all up
            CNumber_Integer res = new CNumber_Integer(Results[0]);

            for (int i = 1; i < cnt; i++)
            {
                res.Addition(Results[i]);
            }

            //CNumber_Integer mul = (CNumber_Integer)other;
            //for (int i = mul._Values.Count - 1; i >= 0; i--)
            //{
            //    CNumber_Integer tmp = (CNumber_Integer) Clone();
            //    tmp.Multiply(mul._Values[i]);
            //    res.Insert(0);
            //    res.Addition(tmp);
            //}

            res._Sign = (_Sign != o._Sign);
            res.Trim();
            return(res);
        }
Ejemplo n.º 15
0
        //------------------------------------------------------------
        // create a string to a base of a power of 2
        protected string toString_2ish_base(uint Base)
        {
            uint bits = log_bin(Base);

            // generate reversed string of digits
            CNumber_Integer tmp = (CNumber_Integer)Clone();
            string          num = String.Empty;
            int             cnt = 0;

            do
            {
                if (cnt == 4)
                {
                    cnt = 0; num += '.';
                }
                uint rem = tmp.ShiftRight(bits);
                num += (char)((rem > 9) ? (rem - 10 + 'A') : (rem + '0'));
                ++cnt;
            } while (!tmp.IsZero);
            return(num);
        }
Ejemplo n.º 16
0
        //------------------------------------------------------------
        // create a string to a base that is not a power of 2
        protected string toString_odd_base(byte Base)
        {
            // numbers of digits separated by '.'
            int step = (Base == 10) ? 3 : 4;

            // generate reversed string of digits
            CNumber_Integer tmp = (CNumber_Integer)Clone();
            string          num = String.Empty;
            int             cnt = 0;

            do
            {
                if (cnt == step)
                {
                    cnt = 0; num += '.';
                }
                uint rem = tmp.Divide(Base);
                num += (char)((rem > 9) ? (rem - 10 + 'A') : (rem + '0'));
                cnt++;
            } while (!tmp.IsZero);
            return(num);
        }
Ejemplo n.º 17
0
        public override bool Equals(MMC.Numbers.CNumber other)
        {
            if (other.MyType != MyType)
            {
                return(false);
            }

            CNumber_Integer o = (CNumber_Integer)other;

            if (size != o.size)
            {
                return(false);
            }

            for (int i = 0; i < size; i++)
            {
                if (_Values[i] != o._Values[i])
                {
                    return(false);
                }
            }
            return(true);
        }
Ejemplo n.º 18
0
        //------------------------------------------------------------
        // add a number
        // the native way to take care of the overflow
        // is checking after the summation if the sum is less than
        // one of the summands, this would mean overflow
        // but this would need some more conditional branches
        // so I choose a way with conversions from byte to uint
        // to let the .Net calc the overflow
        public void Addition(CNumber_Integer other)
        {
            resizeDigits((uint)other.size);                 // make sure we are big enough for both

            uint rem   = 0;                                 // the remainder
            int  o_len = other.size;                        // the other length
            int  t_len = size;                              // our own length
            int  len   = (t_len < o_len) ? t_len : o_len;   // calc the minimum length
            int  i     = 0;                                 // start with the lowest digit

            for (; i < len; ++i)                            // first add all common digits
            {
                rem       += other._Values[i];              // val = rem + val + other.val
                rem       += _Values[i];
                _Values[i] = (byte)rem;
                rem      >>= bitsDigit;                     // rem = overflow
            }

            for (; i < o_len; ++i)                          // now copy the remaining from the other
            {
                rem       += other._Values[i];              // don't forget the remainder
                _Values[i] = (byte)rem;
                rem      >>= bitsDigit;
            }

            for (; (rem > 0) && (i < t_len); ++i)           // now increase our own remaining digits
            {                                               // as long as the remainder is non-zero
                rem       += _Values[i];
                _Values[i] = (byte)rem;
                rem      >>= bitsDigit;
            }
            if (rem > 0)
            {
                AddDigit((byte)rem);                        // still something left, just add it
            }
        }
Ejemplo n.º 19
0
 //------------------------------------------------------------
 // to copy
 protected virtual void CopyFrom(CNumber_Integer other)
 {
     _Values = new List <byte>(other._Values);
     _Sign   = other._Sign;
 }