Beispiel #1
0
        public static long Run()
        {
            //A bit of a struggle to find the right for loop.

            //You substring 13 digits starting from 0 and calculate the greatest product by
            //converting it into an array. You add 1 to the for loop comparision because
            //at index 987 when you substring 13 dights you have gotten the last substring.
            //The product of the numbers is stored in a variable and constantly checked and you
            //always keep track of the largest product and replace only when you have found the
            //largest number, which is what Math.Max will do.

            const string NUMBER   = "7316717653133062491922511967442657474235534919493496983520312774506326239578318016984801869478851843858615607891129494954595017379583319528532088055111254069874715852386305071569329096329522744304355766896648950445244523161731856403098711121722383113622298934233803081353362766142828064444866452387493035890729629049156044077239071381051585930796086670172427121883998797908792274921901699720888093776657273330010533678812202354218097512545405947522435258490771167055601360483958644670632441572215539753697817977846174064955149290862569321978468622482839722413756570560574902614079729686524145351004748216637048440319989000889524345065854122758866688116427171479924442928230863465674813919123162824586178664583591245665294765456828489128831426076900422421902267105562632111110937054421750694165896040807198403850962455444362981230987879927244284909188845801561660979191338754992005240636899125607176060588611646710940507754100225698315520005593572972571636269561882670428252483600823257530420752963450";
            const int    adjacent = 13;
            long         result   = 0;

            for (int i = 0; i + adjacent <= NUMBER.Length; i++)
            {
                string str             = NUMBER.Substring(i, adjacent);
                char[] data            = str.ToCharArray();
                long   adjacentProduct = 1;
                for (int j = 0; j < adjacent; j++)
                {
                    adjacentProduct *= int.Parse(data[j].ToString());
                }
                result = Math.Max(adjacentProduct, result);
            }

            return(result);
        }
Beispiel #2
0
    public CardData(int sign, int number)
    {
        if (!(Enum.IsDefined(typeof(SIGN), sign) && Enum.IsDefined(typeof(NUMBER), number)))
        {
            throw new IndexOutOfRangeException("sign or number is not within correct range");
        }

        this.Sign   = (SIGN)sign;
        this.Number = (NUMBER)number;
    }
Beispiel #3
0
//JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes:
//ORIGINAL LINE: @Test public void shouldCloseAllInstantiated()
        public virtual void ShouldCloseAllInstantiated()
        {
            // given
            System.Func <IndexSlot, string> factory  = SlotToStringFunction();
            LazyInstanceSelector <string>   selector = new LazyInstanceSelector <string>(factory);

            selector.Select(NUMBER);
            selector.Select(STRING);

            // when
            System.Action <string> consumer = mock(typeof(System.Action));
            selector.Close(consumer);

            // then
            verify(consumer, times(1)).accept(NUMBER.ToString());
            verify(consumer, times(1)).accept(STRING.ToString());
            verifyNoMoreInteractions(consumer);
        }
Beispiel #4
0
 private static Boolean HexNumberToInt64(ref NUMBER number, ref Int64 value)
 {
     UInt64 passedValue = 0;
     Boolean returnValue = HexNumberToUInt64(ref number, ref passedValue);
     value = (Int64)passedValue;
     return returnValue;
 }
Beispiel #5
0
        internal unsafe static Boolean NumberBufferToDouble(ref NUMBER number, ref Double value)
        {
            double d = 0;
            NumberToDouble(ref number, &d);
            if ((*(ulong*)(&d) & 0x7FFFFFFFFFFFFFFFL) >= 0x7FF0000000000000L) {
                return false;
            }

            value = d;
            return true;
        }
Beispiel #6
0
        public static String FormatSingle(float value, String format, NumberFormatInfo info)
        {
            NUMBER number;
            int digits;
            double dTest;
            double argsValue = value;

            string retVal;

            char fmt = ParseFormatSpecifier(format, out digits);
            int precision = FLOAT_PRECISION;

            number = new NUMBER();
            switch (fmt & 0xFFD)
            {
                case 'R':
                    //In order to give numbers that are both friendly to display and round-trippable,
                    //we parse the number using 7 digits and then determine if it round trips to the same
                    //value.  If it does, we convert that NUMBER to a string, otherwise we reparse using 9 digits
                    //and display that.
                    DoubleToNumber(argsValue, FLOAT_PRECISION, ref number);

                    if (number.isNan)
                    {
                        retVal = info.NaNSymbol;
                        goto lExit;
                    }

                    if (number.isInf)
                    {
                        retVal = (number.sign ? info.NegativeInfinitySymbol : info.PositiveInfinitySymbol);
                        goto lExit;
                    }

                    unsafe
                    {
                        NumberToDouble(ref number, &dTest);
                    }

                    var fTest = (float)dTest;

                    if (fTest == value)
                    {
                        retVal = NumberToString(ref number, 'G', FLOAT_PRECISION, info);
                        goto lExit;
                    }

                    DoubleToNumber(argsValue, 9, ref number);
                    retVal = NumberToString(ref number, 'G', 9, info);
                    goto lExit;

                case 'E':
                    // Here we round values less than E14 to 15 digits
                    if (digits > 6)
                    {
                        precision = 9;
                    }
                    break;

                case 'G':
                    // Here we round values less than G15 to 15 digits, G16 and G17 will not be touched
                    if (digits > 7)
                    {
                        precision = 9;
                    }
                    break;

            }

            DoubleToNumber(value, precision, ref number);

            if (number.isNan)
            {
                retVal = info.NaNSymbol;
                goto lExit;
            }

            if (number.isInf)
            {
                retVal = (number.sign ? info.NegativeInfinitySymbol : info.PositiveInfinitySymbol);
                goto lExit;
            }

            if (fmt != 0)
            {
                retVal = NumberToString(ref number, fmt, digits, info);
            }
            else
            {
                retVal = NumberToStringFormat(ref number, format, info);
            }

        lExit:
            return retVal;

        }
Beispiel #7
0
        private unsafe static void NumberToDouble(ref NUMBER number, double* value)
        {
            fixed (char* srcPtr = number.digits)
            {
                char* src = srcPtr;
                ulong val;
                int exp;
                int remaining;
                int total;
                int count;
                int scale;
                int absscale;
                int index;

                total = (int)wcslen(src);
                remaining = total;

                // skip the leading zeros
                while (*src == '0')
                {
                    remaining--;
                    src++;
                }

                if (remaining == 0)
                {
                    *value = 0;
                    goto done;
                }

                count = Math.Min(remaining, 9);
                remaining -= count;
                val = DigitsToInt(src, count);

                if (remaining > 0)
                {
                    count = Math.Min(remaining, 9);
                    remaining -= count;

                    // get the denormalized power of 10
                    uint mult = (uint)(rgval64Power10[count - 1] >> (64 - rgexp64Power10[count - 1]));
                    val = ((ulong)((uint)(val)) * (ulong)((uint)(mult))) + DigitsToInt(src + 9, count);
                }

                scale = number.scale - (total - remaining);
                absscale = Math.Abs(scale);
                if (absscale >= 22 * 16)
                {
                    // overflow / underflow
                    *(ulong*)value = (scale > 0) ? (ulong)0x7FF0000000000000 : 0;
                    goto done;
                }

                exp = 64;

                // normalize the mantisa
                if ((val & 0xFFFFFFFF00000000) == 0)
                {
                    val <<= 32;
                    exp -= 32;
                }
                if ((val & 0xFFFF000000000000) == 0)
                {
                    val <<= 16;
                    exp -= 16;
                }
                if ((val & 0xFF00000000000000) == 0)
                {
                    val <<= 8;
                    exp -= 8;
                }
                if ((val & 0xF000000000000000) == 0)
                {
                    val <<= 4;
                    exp -= 4;
                }
                if ((val & 0xC000000000000000) == 0)
                {
                    val <<= 2;
                    exp -= 2;
                }
                if ((val & 0x8000000000000000) == 0)
                {
                    val <<= 1;
                    exp -= 1;
                }

                index = absscale & 15;
                if (index > 0)
                {
                    int multexp = rgexp64Power10[index - 1];
                    // the exponents are shared between the inverted and regular table
                    exp += (scale < 0) ? (-multexp + 1) : multexp;

                    ulong multval = rgval64Power10[index + ((scale < 0) ? 15 : 0) - 1];
                    val = Mul64Lossy(val, multval, &exp);
                }

                index = absscale >> 4;
                if (index > 0)
                {
                    int multexp = rgexp64Power10By16[index - 1];
                    // the exponents are shared between the inverted and regular table
                    exp += (scale < 0) ? (-multexp + 1) : multexp;

                    ulong multval = rgval64Power10By16[index + ((scale < 0) ? 21 : 0) - 1];
                    val = Mul64Lossy(val, multval, &exp);
                }

                // round & scale down
                if (((uint)val & (1 << 10)) > 0)
                {
                    // IEEE round to even
                    ulong tmp = val + ((1 << 10) - 1) + (((uint)val >> 11) & 1);
                    if (tmp < val)
                    {
                        // overflow
                        tmp = (tmp >> 1) | 0x8000000000000000;
                        exp += 1;
                    }
                    val = tmp;
                }
                val >>= 11;

                exp += 0x3FE;

                if (exp <= 0)
                {
                    if (exp <= -52)
                    {
                        // underflow
                        val = 0;
                    }
                    else
                    {
                        // denormalized
                        val >>= (-exp + 1);
                    }
                }
                else if (exp >= 0x7FF)
                {
                    // overflow
                    val = 0x7FF0000000000000;
                }
                else
                {
                    val = ((ulong)exp << 52) + (val & 0x000FFFFFFFFFFFFF);
                }

                *(ulong*)value = val;

                done:
                if (number.sign) *(ulong*)value |= 0x8000000000000000;
            }
        }
Beispiel #8
0
        private static unsafe void UInt64ToNumber(ulong value, ref NUMBER number)
        {
            char* buffer = stackalloc char[ULONG_PRECISION + 1];
            number.precision = ULONG_PRECISION;
            number.sign = false;

            fixed (char* dstPtr = number.digits)
            {
                char* dst = dstPtr;
                char* p = buffer + ULONG_PRECISION;
                while ((value & 0xFFFFFFFF00000000) > 0)
                {
                    p = Int32ToDecChars(p, Int64DivMod1E9(&value), 9);
                }
                p = Int32ToDecChars(p, (uint)value, 0);
                int i = (int)(buffer + ULONG_PRECISION - p);
                number.scale = i;
                while (--i >= 0) *dst++ = *p++;
                *dst = '\0';
            }
        }
Beispiel #9
0
        private static unsafe void UInt32ToNumber(uint value, ref NUMBER number)
        {
            char* buffer = stackalloc char[UINT32_PRECISION + 1];
            number.precision = UINT32_PRECISION;
            number.sign = false;

            fixed (char* dstPtr = number.digits)
            {
                char* dst = dstPtr;
                char* p = Int32ToDecChars(buffer + UINT32_PRECISION, value, 0);
                int i = (int)(buffer + UINT32_PRECISION - p);
                number.scale = i;
                while (--i >= 0) *dst++ = *p++;
                *dst = '\0';
            }
        }
Beispiel #10
0
 public CardData(SIGN sign, NUMBER number)
 {
     this.Sign   = sign;
     this.Number = number;
 }
Beispiel #11
0
 private unsafe static void RoundNumber(ref NUMBER number, int pos)
 {
     fixed (char* digits = number.digits)
     {
         int i = 0;
         while (i < pos && digits[i] != 0)
             i++;
         if (i == pos && digits[i] >= '5')
         {
             while (i > 0 && digits[i - 1] == '9')
                 i--;
             if (i > 0)
             {
                 digits[i - 1]++;
             }
             else
             {
                 number.scale++;
                 digits[0] = '1';
                 i = 1;
             }
         }
         else
         {
             while (i > 0 && digits[i - 1] == '0')
                 i--;
         }
         if (i == 0)
         {
             number.scale = 0;
             number.sign = false;
         }
         digits[i] = '\0';
     }
 }
Beispiel #12
0
        private unsafe static char* FormatPercent(char* buffer, ref NUMBER number, int digits, NumberFormatInfo numfmt)
        {
            char ch;
            var fmtStr = number.sign
                ? negPercentFormats[numfmt.PercentNegativePattern]
                : posPercentFormats[numfmt.PercentPositivePattern];

            fixed (char* fmtPtr = fmtStr)
            {
                char* fmt = fmtPtr;
                while ((ch = *fmt++) != 0)
                {
                    switch (ch)
                    {
                        case '#':
                            buffer = FormatFixed(
                                buffer,
                                ref number,
                                digits,
                                numfmt.PercentGroupSizes,
                                numfmt.PercentDecimalSeparator,
                                numfmt.PercentGroupSeparator);
                            break;
                        case '-':
                            AddStringRef(&buffer, numfmt.NegativeSign);
                            break;
                        case '%':
                            AddStringRef(&buffer, numfmt.PercentSymbol);
                            break;
                        default:
                            *buffer++ = ch;
                            break;
                    }
                }
            }

            return buffer;
        }
Beispiel #13
0
 private unsafe static char* FormatScientific(char* buffer, ref NUMBER number, int digits, char expChar,
     NumberFormatInfo numfmt)
 {
     fixed (char* digPtr = number.digits)
     {
         char* dig = digPtr;
         *buffer++ = *dig != 0 ? *dig++ : '0';
         if (digits != 1) // For E0 we would like to suppress the decimal point
             AddStringRef(&buffer, numfmt.NumberDecimalSeparator);
         while (--digits > 0)
             *buffer++ = *dig != 0 ? *dig++ : '0';
         int e = digPtr[0] == 0 ? 0 : number.scale - 1;
         buffer = FormatExponent(buffer, e, expChar, numfmt.PositiveSign, numfmt.NegativeSign, 3);
         return buffer;
     }
 }
Beispiel #14
0
        private unsafe static char* FormatGeneral(char* buffer, ref NUMBER number, int digits, char expChar,
            NumberFormatInfo numfmt, bool bSuppressScientific = false)
        {
            int digPos = number.scale;
            int scientific = 0;
            if (!bSuppressScientific)
            { // Don't switch to scientific notation
                if (digPos > digits || digPos < -3)
                {
                    digPos = 1;
                    scientific = 1;
                }
            }
            fixed (char* digPtr = number.digits)
            {
                char* dig = digPtr;
                if (digPos > 0)
                {
                    do
                    {
                        *buffer++ = *dig != 0 ? *dig++ : '0';
                    } while (--digPos > 0);
                }
                else
                {
                    *buffer++ = '0';
                }
                if (*dig != 0 || digPos < 0)
                {
                    AddStringRef(&buffer, numfmt.NumberDecimalSeparator);
                    while (digPos < 0)
                    {
                        *buffer++ = '0';
                        digPos++;
                    }
                    while (*dig != 0)
                    {
                        *buffer++ = *dig++;
                    }
                }
                if (scientific > 0)
                    buffer = FormatExponent(
                        buffer,
                        number.scale - 1,
                        expChar,
                        numfmt.PositiveSign,
                        numfmt.NegativeSign,
                        2);
            }

            return buffer;
        }
Beispiel #15
0
        private unsafe static char* FormatFixed(char* buffer, ref NUMBER number, int digits,
            int[] groupDigits, string sDecimal, string sGroup)
        {
            int digPos = number.scale;
            fixed (char* digPtr = number.digits)
            {
                char* dig = digPtr;
                if (digPos > 0)
                {
                    if (groupDigits != null)
                    {

                        int groupSizeIndex = 0; // index into the groupDigits array.
                        int groupSizeCount = groupDigits[groupSizeIndex]; // the current total of group size.
                        int groupSizeLen = groupDigits.Length; // the length of groupDigits array.
                        int bufferSize = digPos; // the length of the result buffer string.
                        int groupSeparatorLen = sGroup.Length; // the length of the group separator string.
                        int groupSize = 0; // the current group size.

                        //
                        // Find out the size of the string buffer for the result.
                        //
                        if (groupSizeLen != 0) // You can pass in 0 length arrays
                        {
                            while (digPos > groupSizeCount)
                            {
                                groupSize = groupDigits[groupSizeIndex];
                                if (groupSize == 0)
                                {
                                    break;
                                }

                                bufferSize += groupSeparatorLen;
                                if (groupSizeIndex < groupSizeLen - 1)
                                {
                                    groupSizeIndex++;
                                }
                                groupSizeCount += groupDigits[groupSizeIndex];
                                if (groupSizeCount < 0 || bufferSize < 0)
                                {
                                    throw new ArgumentOutOfRangeException(); // if we overflow
                                }
                            }
                            if (groupSizeCount == 0)
                                // If you passed in an array with one entry as 0, groupSizeCount == 0
                                groupSize = 0;
                            else
                                groupSize = groupDigits[0];
                        }

                        groupSizeIndex = 0;
                        int digitCount = 0;
                        int digStart;
                        int digLength = (int)wcslen(dig);
                        digStart = (digPos < digLength) ? digPos : digLength;
                        char* p = buffer + bufferSize - 1;
                        for (int i = digPos - 1; i >= 0; i--)
                        {
                            *(p--) = (i < digStart) ? dig[i] : '0';

                            if (groupSize > 0)
                            {
                                digitCount++;
                                if (digitCount == groupSize && i != 0)
                                {
                                    for (int j = groupSeparatorLen - 1; j >= 0; j--)
                                    {
                                        *(p--) = sGroup[j];
                                    }

                                    if (groupSizeIndex < groupSizeLen - 1)
                                    {
                                        groupSizeIndex++;
                                        groupSize = groupDigits[groupSizeIndex];
                                    }
                                    digitCount = 0;
                                }
                            }
                        }
                        if (p < buffer - 1)
                        {
                            // This indicates a buffer underflow since we write in backwards. 
                            throw new OutOfMemoryException();
                        }
                        buffer += bufferSize;
                        dig += digStart;
                    }
                    else
                    {
                        do
                        {
                            *buffer++ = *dig != 0 ? *dig++ : '0';
                        } while (--digPos > 0);
                    }
                }
                else
                {
                    *buffer++ = '0';
                }
                if (digits > 0)
                {
                    AddStringRef(&buffer, sDecimal);
                    while (digPos < 0 && digits > 0)
                    {
                        *buffer++ = '0';
                        digPos++;
                        digits--;
                    }
                    while (digits > 0)
                    {
                        *buffer++ = *dig != 0 ? *dig++ : '0';
                        digits--;
                    }
                }
            }

            return buffer;
        }
Beispiel #16
0
        private unsafe static Boolean NumberToInt64(ref NUMBER number, ref Int64 value)
        {

            Int32 i = number.scale;
            if (i > Int64Precision || i < number.precision)
            {
                return false;
            }

            fixed (char* digits = number.digits)
            {
                char* p = digits;
                Int64 n = 0;
                while (--i >= 0)
                {
                    if ((UInt64)n > (0x7FFFFFFFFFFFFFFF / 10))
                    {
                        return false;
                    }
                    n *= 10;
                    if (*p != '\0')
                    {
                        n += (Int32)(*p++ - '0');
                    }
                }
                if (number.sign)
                {
                    n = -n;
                    if (n > 0)
                    {
                        return false;
                    }
                }
                else
                {
                    if (n < 0)
                    {
                        return false;
                    }
                }
                value = n;
                return true;
            }
        }
Beispiel #17
0
 public static object ParseExcelType(string str, string type)
 {
     if (INT.Equals(type))
     {
         if (string.IsNullOrEmpty(str))
         {
             return(0);
         }
         return(int.Parse(str));
     }
     else if (NUMBER.Equals(type))
     {
         if (string.IsNullOrEmpty(str))
         {
             return(0);
         }
         return(LockStepConst.ParseInLevelInt(str));
     }
     else if (FLOAT.Equals(type))
     {
         if (string.IsNullOrEmpty(str))
         {
             return(0);
         }
         return(float.Parse(str));
     }
     else if (STRING.Equals(type))
     {
         return(str);
     }
     else if (BOOL.Equals(type))
     {
         return("true".Equals(str.ToLower()));
     }
     else if (LINT.Equals(type))
     {
         string[]   p      = str.SplitStringBySplits();
         List <int> result = new List <int>(p.Length);
         for (int i = 0; i < p.Length; i++)
         {
             if (string.IsNullOrEmpty(str))
             {
                 result.Add(0);
             }
             else
             {
                 result.Add(int.Parse(p[i]));
             }
         }
         return(result);
     }
     else if (LNUMBER.Equals(type))
     {
         string[]   p      = str.SplitStringBySplits();
         List <int> result = new List <int>(p.Length);
         for (int i = 0; i < p.Length; i++)
         {
             if (string.IsNullOrEmpty(str))
             {
                 result.Add(0);
             }
             else
             {
                 result.Add(LockStepConst.ParseInLevelInt(p[i]));
             }
         }
         return(result);
     }
     else if (LFLOAT.Equals(type))
     {
         string[]     p      = str.SplitStringBySplits();
         List <float> result = new List <float>(p.Length);
         for (int i = 0; i < p.Length; i++)
         {
             if (string.IsNullOrEmpty(str))
             {
                 result.Add(0);
             }
             else
             {
                 result.Add(float.Parse(p[i]));
             }
         }
         return(result);
     }
     else if (LSTRING.Equals(type))
     {
         string[]      p      = str.SplitStringBySplits();
         List <string> result = new List <string>(p.Length);
         for (int i = 0; i < p.Length; i++)
         {
             result.Add(p[i]);
         }
         return(result);
     }
     else if (LBOOL.Equals(type))
     {
         string[]    p      = str.SplitStringBySplits();
         List <bool> result = new List <bool>(p.Length);
         for (int i = 0; i < p.Length; i++)
         {
             result.Add("true".Equals(str));
         }
         return(result);
     }
     return(null);
 }
Beispiel #18
0
        internal unsafe static Decimal ParseDecimal(String value, NumberStyles options, NumberFormatInfo numfmt)
        {

            
            NUMBER number = new NUMBER();
            Decimal result = 0;

            StringToNumber(value, options, ref number, numfmt, true);

            if (!NumberBufferToDecimal(ref number, ref result))
            {
                throw new OverflowException(Environment.GetResourceString("Overflow_Decimal"));
            }
            return result;
        }
Beispiel #19
0
        internal unsafe static Boolean TryStringToNumber(String str, NumberStyles options, ref NUMBER number, StringBuilder sb, NumberFormatInfo numfmt, Boolean parseDecimal)
        {

            if (str == null)
            {
                return false;
            }

            fixed (char* stringPointer = str)
            {
                char* p = stringPointer;
                if (!ParseNumber(ref p, options, ref number, sb, numfmt, parseDecimal)
                    || (p - stringPointer < str.Length && !TrailingZeros(str, (int)(p - stringPointer))))
                {
                    return false;
                }
            }

            return true;
        }
Beispiel #20
0
        internal unsafe static Int32 ParseInt32(String s, NumberStyles style, NumberFormatInfo info)
        {

            
            NUMBER number = new NUMBER();
            Int32 i = 0;

            StringToNumber(s, style, ref number, info, false);

            if ((style & NumberStyles.AllowHexSpecifier) != 0)
            {
                if (!HexNumberToInt32(ref number, ref i))
                {
                    throw new OverflowException(Environment.GetResourceString("Overflow_Int32"));
                }
            }
            else
            {
                if (!NumberToInt32(ref number, ref i))
                {
                    throw new OverflowException(Environment.GetResourceString("Overflow_Int32"));
                }
            }
            return i;
        }
Beispiel #21
0
        private static unsafe void Int64ToNumber(long value, ref NUMBER number)
        {
            char* buffer = stackalloc char[LONG_PRECISION + 1];
            number.precision = LONG_PRECISION;
            if (value >= 0)
            {
                number.sign = false;
            }
            else
            {
                number.sign = true;
            }

            fixed (char* dstPtr = number.digits)
            {
                char* dst = dstPtr;
                char* p = buffer + LONG_PRECISION;
                if (value >= 0)
                {
                    while (((ulong)value & 0xFFFFFFFF00000000) > 0)
                    {
                        p = Int32ToDecChars(p, Int64DivMod1E9(&value), 9);
                    }
                }
                else
                {
                    while ((((ulong)value ^ 0xFFFFFFFF00000000) >> 32) > 0)
                    {
                        p = Int32ToDecChars(p, Int64DivMod1E9(&value), 9);
                    }
                }

                p = Int32ToDecChars(p, (int)value, 0);

                int i = (int)(buffer + LONG_PRECISION - p);
                number.scale = i;
                while (--i >= 0) *dst++ = *p++;
                *dst = '\0';
            }
        }
Beispiel #22
0
        private unsafe static Boolean ParseNumber(ref char* str, NumberStyles options, ref NUMBER number, StringBuilder sb, NumberFormatInfo numfmt, Boolean parseDecimal)
        {

            const Int32 StateSign = 0x0001;
            const Int32 StateParens = 0x0002;
            const Int32 StateDigits = 0x0004;
            const Int32 StateNonZero = 0x0008;
            const Int32 StateDecimal = 0x0010;
            const Int32 StateCurrency = 0x0020;

            number.scale = 0;
            number.sign = false;
            string decSep;                  // decimal separator from NumberFormatInfo.
            string groupSep;                // group separator from NumberFormatInfo.
            string currSymbol = null;       // currency symbol from NumberFormatInfo.

            // The alternative currency symbol used in ANSI codepage, that can not roundtrip between ANSI and Unicode.
            // Currently, only ja-JP and ko-KR has non-null values (which is U+005c, backslash)
            string ansicurrSymbol = null;   // currency symbol from NumberFormatInfo.
            string altdecSep = null;        // decimal separator from NumberFormatInfo as a decimal
            string altgroupSep = null;      // group separator from NumberFormatInfo as a decimal

            Boolean parsingCurrency = false;
            if ((options & NumberStyles.AllowCurrencySymbol) != 0)
            {
                currSymbol = numfmt.CurrencySymbol;
                if (numfmt.ansiCurrencySymbol != null)
                {
                    ansicurrSymbol = numfmt.ansiCurrencySymbol;
                }
                // The idea here is to match the currency separators and on failure match the number separators to keep the perf of VB's IsNumeric fast.
                // The values of decSep are setup to use the correct relevant separator (currency in the if part and decimal in the else part).
                altdecSep = numfmt.NumberDecimalSeparator;
                altgroupSep = numfmt.NumberGroupSeparator;
                decSep = numfmt.CurrencyDecimalSeparator;
                groupSep = numfmt.CurrencyGroupSeparator;
                parsingCurrency = true;
            }
            else
            {
                decSep = numfmt.NumberDecimalSeparator;
                groupSep = numfmt.NumberGroupSeparator;
            }

            Int32 state = 0;
            Boolean signflag = false; // Cache the results of "options & PARSE_LEADINGSIGN && !(state & STATE_SIGN)" to avoid doing this twice
            Boolean bigNumber = (sb != null); // When a StringBuilder is provided then we use it in place of the number.digits char[50]
            Boolean bigNumberHex = (bigNumber && ((options & NumberStyles.AllowHexSpecifier) != 0));
            Int32 maxParseDigits = bigNumber ? Int32.MaxValue : NumberMaxDigits;

            fixed (char* digits = number.digits)
            {
                char* p = str;
                char ch = *p;
                char* next;

                while (true)
                {
                    // Eat whitespace unless we've found a sign which isn't followed by a currency symbol.
                    // "-Kr 1231.47" is legal but "- 1231.47" is not.
                    if (IsWhite(ch) && ((options & NumberStyles.AllowLeadingWhite) != 0)
                        && (((state & StateSign) == 0) || (((state & StateSign) != 0) && (((state & StateCurrency) != 0) || numfmt.numberNegativePattern == 2))))
                    {
                        // Do nothing here. We will increase p at the end of the loop.
                    }
                    else if ((signflag = (((options & NumberStyles.AllowLeadingSign) != 0) && ((state & StateSign) == 0)))
                             && ((next = MatchChars(p, numfmt.positiveSign)) != null))
                    {
                        state |= StateSign;
                        p = next - 1;
                    }
                    else if (signflag && (next = MatchChars(p, numfmt.negativeSign)) != null)
                    {
                        state |= StateSign;
                        number.sign = true;
                        p = next - 1;
                    }
                    else if (ch == '(' && ((options & NumberStyles.AllowParentheses) != 0) && ((state & StateSign) == 0))
                    {
                        state |= StateSign | StateParens;
                        number.sign = true;
                    }
                    else if ((currSymbol != null && (next = MatchChars(p, currSymbol)) != null)
                             || (ansicurrSymbol != null && (next = MatchChars(p, ansicurrSymbol)) != null))
                    {
                        state |= StateCurrency;
                        currSymbol = null;
                        ansicurrSymbol = null;
                        // We already found the currency symbol. There should not be more currency symbols. Set
                        // currSymbol to null so that we won't search it again in the later code path.
                        p = next - 1;
                    }
                    else
                    {
                        break;
                    }
                    ch = *++p;
                }
                Int32 digCount = 0;
                Int32 digEnd = 0;
                while (true)
                {
                    if ((ch >= '0' && ch <= '9')
                        || (((options & NumberStyles.AllowHexSpecifier) != 0) && ((ch >= 'a' && ch <= 'f') || (ch >= 'A' && ch <= 'F'))))
                    {
                        state |= StateDigits;

                        if (ch != '0' || (state & StateNonZero) != 0 || bigNumberHex)
                        {
                            if (digCount < maxParseDigits)
                            {
                                if (bigNumber) sb.Append(ch);
                                else digits[digCount++] = ch;
                                if (ch != '0' || parseDecimal)
                                {
                                    digEnd = digCount;
                                }
                            }
                            if ((state & StateDecimal) == 0)
                            {
                                number.scale++;
                            }
                            state |= StateNonZero;
                        }
                        else if ((state & StateDecimal) != 0)
                        {
                            number.scale--;
                        }
                    }
                    else if (((options & NumberStyles.AllowDecimalPoint) != 0) && ((state & StateDecimal) == 0)
                             && ((next = MatchChars(p, decSep)) != null
                                 || ((parsingCurrency) && (state & StateCurrency) == 0) && (next = MatchChars(p, altdecSep)) != null))
                    {
                        state |= StateDecimal;
                        p = next - 1;
                    }
                    else if (((options & NumberStyles.AllowThousands) != 0) && ((state & StateDigits) != 0) && ((state & StateDecimal) == 0)
                             && ((next = MatchChars(p, groupSep)) != null
                                 || ((parsingCurrency) && (state & StateCurrency) == 0) && (next = MatchChars(p, altgroupSep)) != null))
                    {
                        p = next - 1;
                    }
                    else
                    {
                        break;
                    }
                    ch = *++p;
                }

                Boolean negExp = false;
                number.precision = digEnd;
                if (bigNumber) sb.Append('\0');
                else digits[digEnd] = '\0';
                if ((state & StateDigits) != 0)
                {
                    if ((ch == 'E' || ch == 'e') && ((options & NumberStyles.AllowExponent) != 0))
                    {
                        char* temp = p;
                        ch = *++p;
                        if ((next = MatchChars(p, numfmt.positiveSign)) != null)
                        {
                            ch = *(p = next);
                        }
                        else if ((next = MatchChars(p, numfmt.negativeSign)) != null)
                        {
                            ch = *(p = next);
                            negExp = true;
                        }
                        if (ch >= '0' && ch <= '9')
                        {
                            Int32 exp = 0;
                            do
                            {
                                exp = exp * 10 + (ch - '0');
                                ch = *++p;
                                if (exp > 1000)
                                {
                                    exp = 9999;
                                    while (ch >= '0' && ch <= '9')
                                    {
                                        ch = *++p;
                                    }
                                }
                            }
                            while (ch >= '0' && ch <= '9');
                            if (negExp)
                            {
                                exp = -exp;
                            }
                            number.scale += exp;
                        }
                        else
                        {
                            p = temp;
                            ch = *p;
                        }
                    }
                    while (true)
                    {
                        if (IsWhite(ch) && ((options & NumberStyles.AllowTrailingWhite) != 0))
                        {
                        }
                        else if ((signflag = (((options & NumberStyles.AllowTrailingSign) != 0) && ((state & StateSign) == 0)))
                                 && (next = MatchChars(p, numfmt.positiveSign)) != null)
                        {
                            state |= StateSign;
                            p = next - 1;
                        }
                        else if (signflag && (next = MatchChars(p, numfmt.negativeSign)) != null)
                        {
                            state |= StateSign;
                            number.sign = true;
                            p = next - 1;
                        }
                        else if (ch == ')' && ((state & StateParens) != 0))
                        {
                            state &= ~StateParens;
                        }
                        else if ((currSymbol != null && (next = MatchChars(p, currSymbol)) != null)
                                 || (ansicurrSymbol != null && (next = MatchChars(p, ansicurrSymbol)) != null))
                        {
                            currSymbol = null;
                            ansicurrSymbol = null;
                            p = next - 1;
                        }
                        else
                        {
                            break;
                        }
                        ch = *++p;
                    }
                    if ((state & StateParens) == 0)
                    {
                        if ((state & StateNonZero) == 0)
                        {
                            if (!parseDecimal)
                            {
                                number.scale = 0;
                            }
                            if ((state & StateDecimal) == 0)
                            {
                                number.sign = false;
                            }
                        }
                        str = p;
                        return true;
                    }
                }
                str = p;
                return false;
            }
        }
Beispiel #23
0
        private unsafe static void DoubleToNumber(double value, int precision, ref NUMBER number)
        {
            fixed (char* dstPtr = number.digits)
            {
                if ((*(ulong*)(&value) & 0x7FFFFFFFFFFFFFFFL) >= 0x7FF0000000000000L)
                {
                    var isNaN = Double.IsNaN(value);
                    number.scale = isNaN ? SCALE_NAN : SCALE_INF;
                    number.sign = Double.IsNegative(value);
                    number.isNan = isNaN;
                    number.isInf = !isNaN;
                    *dstPtr = '\0';
                    return;
                }

                number.precision = precision;
                char* dst = dstPtr;
                char* src = DoubleHelper.ecvt(value, precision, ref number.scale, ref number.sign);
                if (*src != '0')
                {
                    while (*src > 0) *dst++ = *src++;
                }

                *dst = '\0';
            }
        }
Beispiel #24
0
        internal unsafe static Single ParseSingle(String value, NumberStyles options, NumberFormatInfo numfmt)
        {
            if (value == null)
            {
                throw new ArgumentNullException("value");
            }

            
            NUMBER number = new NUMBER();
            Double d = 0;

            if (!TryStringToNumber(value, options, ref number, numfmt, false))
            {
                //If we failed TryStringToNumber, it may be from one of our special strings.
                //Check the three with which we're concerned and rethrow if it's not one of
                //those strings.
                String sTrim = value.Trim();
                if (sTrim.Equals(numfmt.PositiveInfinitySymbol))
                {
                    return Single.PositiveInfinity;
                }
                if (sTrim.Equals(numfmt.NegativeInfinitySymbol))
                {
                    return Single.NegativeInfinity;
                }
                if (sTrim.Equals(numfmt.NaNSymbol))
                {
                    return Single.NaN;
                }
                throw new FormatException(Environment.GetResourceString("Format_InvalidString"));
            }

            if (!NumberBufferToDouble(ref number, ref d))
            {
                throw new OverflowException(Environment.GetResourceString("Overflow_Single"));
            }
            Single castSingle = (Single)d;
            if (Single.IsInfinity(castSingle))
            {
                throw new OverflowException(Environment.GetResourceString("Overflow_Single"));
            }
            return castSingle;
        }
Beispiel #25
0
        public static String FormatUInt64(ulong value, String format, NumberFormatInfo info)
        {
            int digits;
            var fmt = ParseFormatSpecifier(format, out digits);

            var retString = string.Empty;

            NUMBER number;

            //ANDing fmt with FFDF has the effect of uppercasing the character because
            //we've removed the bit that marks lower-case.
            switch (fmt & 0xFFDF)
            {
                case 'G':
                    if (digits > 0)
                    {
                        number = new NUMBER();
                        UInt64ToNumber(value, ref number);
                        if (fmt != 0)
                        {
                            retString = NumberToString(ref number, fmt, digits, info);
                            break;
                        }
                        retString = NumberToStringFormat(ref number, format, info);
                        break;
                    }

                    goto case 'D';

                // fall through
                case 'D':
                    retString = UInt64ToDecStr(value, digits);
                    break;
                case 'X':
                    retString = Int64ToHexStr(value, fmt - ('X' - 'A' + 10), digits);
                    break;
                default:
                    number = new NUMBER();
                    UInt64ToNumber(value, ref number);
                    if (fmt != 0)
                    {
                        retString = NumberToString(ref number, fmt, digits, info);
                        break;
                    }
                    retString = NumberToStringFormat(ref number, format, info);
                    break;

            }

            return retString;
        }
Beispiel #26
0
        internal unsafe static UInt64 ParseUInt64(String value, NumberStyles options, NumberFormatInfo numfmt)
        {
            
            NUMBER number = new NUMBER();
            UInt64 i = 0;

            StringToNumber(value, options, ref number, numfmt, false);
            if ((options & NumberStyles.AllowHexSpecifier) != 0)
            {
                if (!HexNumberToUInt64(ref number, ref i))
                {
                    throw new OverflowException(Environment.GetResourceString("Overflow_UInt64"));
                }
            }
            else
            {
                if (!NumberToUInt64(ref number, ref i))
                {
                    throw new OverflowException(Environment.GetResourceString("Overflow_UInt64"));
                }
            }
            return i;
        }
Beispiel #27
0
 public unsafe static Boolean NumberBufferToDecimal(ref NUMBER number, ref Decimal value)
 {
     throw new NotImplementedException();
 }
Beispiel #28
0
        private unsafe static void StringToNumber(String str, NumberStyles options, ref NUMBER number, NumberFormatInfo info, Boolean parseDecimal)
        {

            if (str == null)
            {
                throw new ArgumentNullException("String");
            }

            fixed (char* stringPointer = str)
            {
                char* p = stringPointer;
                if (!ParseNumber(ref p, options, ref number, null, info, parseDecimal)
                    || (p - stringPointer < str.Length && !TrailingZeros(str, (int)(p - stringPointer))))
                {
                    throw new FormatException(Environment.GetResourceString("Format_InvalidString"));
                }
            }
        }
Beispiel #29
0
 internal static unsafe string FormatNumberBuffer(ref NUMBER number, string format, NumberFormatInfo info, char* allDigits)
 {
     throw new NotImplementedException();
 }
Beispiel #30
0
        internal unsafe static Boolean TryParseDouble(String value, NumberStyles options, NumberFormatInfo numfmt, out Double result)
        {
            
            NUMBER number = new NUMBER();
            result = 0;


            if (!TryStringToNumber(value, options, ref number, numfmt, false))
            {
                return false;
            }
            if (!NumberBufferToDouble(ref number, ref result))
            {
                return false;
            }
            return true;
        }
Beispiel #31
0
        private unsafe static Boolean HexNumberToUInt64(ref NUMBER number, ref UInt64 value)
        {

            Int32 i = number.scale;
            if (i > UInt64Precision || i < number.precision)
            {
                return false;
            }
            fixed (Char* digits = number.digits)
            {
                Char* p = digits;
                UInt64 n = 0;
                while (--i >= 0)
                {
                    if (n > (0xFFFFFFFFFFFFFFFF / 16))
                    {
                        return false;
                    }
                    n *= 16;
                    if (*p != '\0')
                    {
                        UInt64 newN = n;
                        if (*p != '\0')
                        {
                            if (*p >= '0' && *p <= '9')
                            {
                                newN += (UInt64)(*p - '0');
                            }
                            else
                            {
                                if (*p >= 'A' && *p <= 'F')
                                {
                                    newN += (UInt64)((*p - 'A') + 10);
                                }
                                else
                                {
                                    newN += (UInt64)((*p - 'a') + 10);
                                }
                            }
                            p++;
                        }

                        // Detect an overflow here...
                        if (newN < n)
                        {
                            return false;
                        }
                        n = newN;
                    }
                }
                value = n;
                return true;
            }
        }
Beispiel #32
0
        internal unsafe static Boolean TryParseSingle(String value, NumberStyles options, NumberFormatInfo numfmt, out Single result)
        {
            
            NUMBER number = new NUMBER();
            result = 0;
            Double d = 0;

            if (!TryStringToNumber(value, options, ref number, numfmt, false))
            {
                return false;
            }
            if (!NumberBufferToDouble(ref number, ref d))
            {
                return false;
            }
            Single castSingle = (Single)d;
            if (Single.IsInfinity(castSingle))
            {
                return false;
            }

            result = castSingle;
            return true;
        }
Beispiel #33
0
        private unsafe static Boolean NumberToUInt32(ref NUMBER number, ref UInt32 value)
        {

            Int32 i = number.scale;
            if (i > UInt32Precision || i < number.precision || number.sign)
            {
                return false;
            }

            fixed (char* digits = number.digits)
            {
                char* p = digits;
                UInt32 n = 0;
                while (--i >= 0)
                {
                    if (n > (0xFFFFFFFF / 10))
                    {
                        return false;
                    }
                    n *= 10;
                    if (*p != '\0')
                    {
                        UInt32 newN = n + (UInt32)(*p++ - '0');
                        // Detect an overflow here...
                        if (newN < n)
                        {
                            return false;
                        }
                        n = newN;
                    }
                }
                value = n;
                return true;
            }
        }
Beispiel #34
0
        internal unsafe static Boolean TryParseUInt64(String s, NumberStyles style, NumberFormatInfo info, out UInt64 result)
        {

            
            NUMBER number = new NUMBER();
            result = 0;

            if (!TryStringToNumber(s, style, ref number, info, false))
            {
                return false;
            }

            if ((style & NumberStyles.AllowHexSpecifier) != 0)
            {
                if (!HexNumberToUInt64(ref number, ref result))
                {
                    return false;
                }
            }
            else
            {
                if (!NumberToUInt64(ref number, ref result))
                {
                    return false;
                }
            }
            return true;
        }
Beispiel #35
0
 internal static Boolean TryStringToNumber(String str, NumberStyles options, ref NUMBER number, NumberFormatInfo numfmt, Boolean parseDecimal)
 {
     return TryStringToNumber(str, options, ref number, null, numfmt, parseDecimal);
 }
Beispiel #36
0
 public CardData()
 {
     Sign   = SIGN.Spade;
     Number = NUMBER.NotANumber;
 }