AsBigInteger() 개인적인 메소드

private AsBigInteger ( ) : PeterO.Numbers.EInteger
리턴 PeterO.Numbers.EInteger
예제 #1
0
        /// <include file='../../docs.xml'
        /// path='docs/doc[@name="M:PeterO.Cbor.CBORDataUtilities.ParseJSONNumber(System.String,System.Boolean,System.Boolean,System.Boolean)"]/*'/>
        public static CBORObject ParseJSONNumber(
            string str,
            bool integersOnly,
            bool positiveOnly,
            bool preserveNegativeZero)
        {
            if (String.IsNullOrEmpty(str))
            {
                return(null);
            }
            var offset   = 0;
            var negative = false;

            if (str[0] == '-' && !positiveOnly)
            {
                negative = true;
                ++offset;
            }
            var          mantInt                = 0;
            FastInteger2 mant                   = null;
            var          mantBuffer             = 0;
            var          mantBufferMult         = 1;
            var          expBuffer              = 0;
            var          expBufferMult          = 1;
            var          haveDecimalPoint       = false;
            var          haveDigits             = false;
            var          haveDigitsAfterDecimal = false;
            var          haveExponent           = false;
            var          newScaleInt            = 0;
            FastInteger2 newScale               = null;
            int          i = offset;

            // Ordinary number
            if (i < str.Length && str[i] == '0')
            {
                ++i;
                haveDigits = true;
                if (i == str.Length)
                {
                    if (preserveNegativeZero && negative)
                    {
                        return(CBORObject.FromObject(
                                   EDecimal.NegativeZero));
                    }
                    return(CBORObject.FromObject(0));
                }
                if (!integersOnly)
                {
                    if (str[i] == '.')
                    {
                        haveDecimalPoint = true;
                        ++i;
                    }
                    else if (str[i] == 'E' || str[i] == 'e')
                    {
                        haveExponent = true;
                    }
                    else
                    {
                        return(null);
                    }
                }
                else
                {
                    return(null);
                }
            }
            for (; i < str.Length; ++i)
            {
                if (str[i] >= '0' && str[i] <= '9')
                {
                    var thisdigit = (int)(str[i] - '0');
                    if (mantInt > MaxSafeInt)
                    {
                        if (mant == null)
                        {
                            mant           = new FastInteger2(mantInt);
                            mantBuffer     = thisdigit;
                            mantBufferMult = 10;
                        }
                        else
                        {
                            if (mantBufferMult >= 1000000000)
                            {
                                mant.Multiply(mantBufferMult).AddInt(mantBuffer);
                                mantBuffer     = thisdigit;
                                mantBufferMult = 10;
                            }
                            else
                            {
                                mantBufferMult *= 10;
                                mantBuffer      = (mantBuffer << 3) + (mantBuffer << 1);
                                mantBuffer     += thisdigit;
                            }
                        }
                    }
                    else
                    {
                        mantInt *= 10;
                        mantInt += thisdigit;
                    }
                    haveDigits = true;
                    if (haveDecimalPoint)
                    {
                        haveDigitsAfterDecimal = true;
                        if (newScaleInt == Int32.MinValue)
                        {
                            newScale = newScale ?? (new FastInteger2(newScaleInt));
                            newScale.AddInt(-1);
                        }
                        else
                        {
                            --newScaleInt;
                        }
                    }
                }
                else if (!integersOnly && str[i] == '.')
                {
                    if (!haveDigits)
                    {
                        // no digits before the decimal point
                        return(null);
                    }
                    if (haveDecimalPoint)
                    {
                        return(null);
                    }
                    haveDecimalPoint = true;
                }
                else if (!integersOnly && (str[i] == 'E' || str[i] == 'e'))
                {
                    haveExponent = true;
                    ++i;
                    break;
                }
                else
                {
                    return(null);
                }
            }
            if (!haveDigits || (haveDecimalPoint && !haveDigitsAfterDecimal))
            {
                return(null);
            }
            if (mant != null && (mantBufferMult != 1 || mantBuffer != 0))
            {
                mant.Multiply(mantBufferMult).AddInt(mantBuffer);
            }
            if (haveExponent)
            {
                FastInteger2 exp    = null;
                var          expInt = 0;
                offset     = 1;
                haveDigits = false;
                if (i == str.Length)
                {
                    return(null);
                }
                if (str[i] == '+' || str[i] == '-')
                {
                    if (str[i] == '-')
                    {
                        offset = -1;
                    }
                    ++i;
                }
                for (; i < str.Length; ++i)
                {
                    if (str[i] >= '0' && str[i] <= '9')
                    {
                        haveDigits = true;
                        var thisdigit = (int)(str[i] - '0');
                        if (expInt > MaxSafeInt)
                        {
                            if (exp == null)
                            {
                                exp           = new FastInteger2(expInt);
                                expBuffer     = thisdigit;
                                expBufferMult = 10;
                            }
                            else
                            {
                                if (expBufferMult >= 1000000000)
                                {
                                    exp.Multiply(expBufferMult).AddInt(expBuffer);
                                    expBuffer     = thisdigit;
                                    expBufferMult = 10;
                                }
                                else
                                {
                                    // multiply expBufferMult and expBuffer each by 10
                                    expBufferMult = (expBufferMult << 3) + (expBufferMult << 1);
                                    expBuffer     = (expBuffer << 3) + (expBuffer << 1);
                                    expBuffer    += thisdigit;
                                }
                            }
                        }
                        else
                        {
                            expInt *= 10;
                            expInt += thisdigit;
                        }
                    }
                    else
                    {
                        return(null);
                    }
                }
                if (!haveDigits)
                {
                    return(null);
                }
                if (exp != null && (expBufferMult != 1 || expBuffer != 0))
                {
                    exp.Multiply(expBufferMult).AddInt(expBuffer);
                }
                if (offset >= 0 && newScaleInt == 0 && newScale == null && exp == null)
                {
                    newScaleInt = expInt;
                }
                else if (exp == null)
                {
                    newScale = newScale ?? (new FastInteger2(newScaleInt));
                    if (offset < 0)
                    {
                        newScale.SubtractInt(expInt);
                    }
                    else if (expInt != 0)
                    {
                        newScale.AddInt(expInt);
                    }
                }
                else
                {
                    newScale = newScale ?? (new FastInteger2(newScaleInt));
                    if (offset < 0)
                    {
                        newScale.Subtract(exp);
                    }
                    else
                    {
                        newScale.Add(exp);
                    }
                }
            }
            if (i != str.Length)
            {
                // End of the string wasn't reached, so isn't a number
                return(null);
            }
            if ((newScale == null && newScaleInt == 0) || (newScale != null &&
                                                           newScale.Sign == 0))
            {
                // No fractional part
                if (mant != null && mant.CanFitInInt32())
                {
                    mantInt = mant.AsInt32();
                    mant    = null;
                }
                if (mant == null)
                {
                    // NOTE: mantInt can only be 0 or greater, so overflow is impossible
#if DEBUG
                    if (mantInt < 0)
                    {
                        throw new ArgumentException("mantInt (" + mantInt +
                                                    ") is less than 0");
                    }
#endif

                    if (negative)
                    {
                        mantInt = -mantInt;
                        if (preserveNegativeZero && mantInt == 0)
                        {
                            return(CBORObject.FromObject(
                                       EDecimal.NegativeZero));
                        }
                    }
                    return(CBORObject.FromObject(mantInt));
                }
                else
                {
                    EInteger bigmant2 = mant.AsBigInteger();
                    if (negative)
                    {
                        bigmant2 = -(EInteger)bigmant2;
                    }
                    return(CBORObject.FromObject(bigmant2));
                }
            }
            else
            {
                EInteger bigmant = (mant == null) ? ((EInteger)mantInt) :
                                   mant.AsBigInteger();
                EInteger bigexp = (newScale == null) ? ((EInteger)newScaleInt) :
                                  newScale.AsBigInteger();
                if (negative)
                {
                    bigmant = -(EInteger)bigmant;
                }
                EDecimal edec;
                edec = EDecimal.Create(
                    bigmant,
                    bigexp);
                if (negative && preserveNegativeZero && bigmant.IsZero)
                {
                    EDecimal negzero = EDecimal.NegativeZero;
                    negzero = negzero.Quantize(bigexp, null);
                    edec    = negzero.Subtract(edec);
                }
                return(CBORObject.FromObject(edec));
            }
        }
예제 #2
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
                {
                    this.integerMode = 2;
                    this.largeValue  = (EInteger)this.smallValue;
                    valValue         = val.AsBigInteger();
                    this.largeValue += (EInteger)valValue;
                }
                break;

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

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

            default: throw new InvalidOperationException();
            }
            return(this);
        }
예제 #3
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;
 }
예제 #4
0
        /// <summary>Internal API.</summary>
        /// <param name='val'>The parameter <paramref name='val'/> is an
        /// internal parameter.</param>
        /// <returns>A FastInteger2 object.</returns>
        internal FastInteger2 Subtract(FastInteger2 val)
        {
            EInteger valValue;

            switch (this.integerMode)
            {
            case 0:
                if (val.integerMode == 0)
                {
                    int vsv = val.smallValue;
                    if ((vsv < 0 && Int32.MaxValue + vsv < this.smallValue) ||
                        (vsv > 0 && Int32.MinValue + vsv > this.smallValue))
                    {
                        // would overflow, convert to large
                        this.integerMode = 2;
                        this.largeValue  = (EInteger)this.smallValue;
                        this.largeValue -= (EInteger)vsv;
                    }
                    else
                    {
                        this.smallValue -= vsv;
                    }
                }
                else
                {
                    this.integerMode = 2;
                    this.largeValue  = (EInteger)this.smallValue;
                    valValue         = val.AsBigInteger();
                    this.largeValue -= (EInteger)valValue;
                }
                break;

            case 1:
                if (val.integerMode == 1)
                {
                    // NOTE: Mutable numbers are
                    // currently always zero or positive
                    this.mnum.Subtract(val.mnum);
                }
                else if (val.integerMode == 0 && val.smallValue >= 0)
                {
                    this.mnum.SubtractInt(val.smallValue);
                }
                else
                {
                    this.integerMode = 2;
                    this.largeValue  = this.mnum.ToEInteger();
                    valValue         = val.AsBigInteger();
                    this.largeValue -= (EInteger)valValue;
                }
                break;

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

            default: throw new InvalidOperationException();
            }
            return(this);
        }
예제 #5
0
 /// <include file='../../docs.xml'
 /// path='docs/doc[@name="M:PeterO.Cbor.FastInteger2.Subtract(PeterO.Cbor.FastInteger2)"]/*'/>
 internal FastInteger2 Subtract(FastInteger2 val)
 {
     EInteger valValue;
       switch (this.integerMode) {
     case 0:
       if (val.integerMode == 0) {
     int vsv = val.smallValue;
     if ((vsv < 0 && Int32.MaxValue + vsv < this.smallValue) ||
         (vsv > 0 && Int32.MinValue + vsv > this.smallValue)) {
       // would overflow, convert to large
       this.integerMode = 2;
       this.largeValue = (EInteger)this.smallValue;
       this.largeValue -= (EInteger)vsv;
     } else {
       this.smallValue -= vsv;
     }
       } else {
     integerMode = 2;
     largeValue = (EInteger)smallValue;
     valValue = val.AsBigInteger();
     largeValue -= (EInteger)valValue;
       }
       break;
     case 1:
       if (val.integerMode == 1) {
     // NOTE: Mutable numbers are
     // currently always zero or positive
     this.mnum.Subtract(val.mnum);
       } else if (val.integerMode == 0 && val.smallValue >= 0) {
     mnum.SubtractInt(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;
 }