System.Globalization.FormatProvider.Number.NumberToStringFormat C# (CSharp) Méthode

NumberToStringFormat() static private méthode

static private NumberToStringFormat ( NumberBuffer number, string format, NumberFormatInfo info ) : string
number NumberBuffer
format string
info NumberFormatInfo
Résultat string
            internal static unsafe string NumberToStringFormat(NumberBuffer number, string format, NumberFormatInfo info)
            {
                int digitCount;
                int decimalPos;
                int firstDigit;
                int lastDigit;
                int digPos;
                bool scientific;
                int thousandPos;
                int thousandCount = 0;
                bool thousandSeps;
                int scaleAdjust;
                int adjust;

                int section;
                int src;
                char* dig = number.digits;
                char ch;

                section = FindSection(format, dig[0] == 0 ? 2 : number.sign ? 1 : 0);

                while (true)
                {
                    digitCount = 0;
                    decimalPos = -1;
                    firstDigit = 0x7FFFFFFF;
                    lastDigit = 0;
                    scientific = false;
                    thousandPos = -1;
                    thousandSeps = false;
                    scaleAdjust = 0;
                    src = section;

                    fixed (char* pFormat = format)
                    {
                        while ((ch = pFormat[src++]) != 0 && ch != ';')
                        {
                            switch (ch)
                            {
                                case '#':
                                    digitCount++;
                                    break;
                                case '0':
                                    if (firstDigit == 0x7FFFFFFF)
                                        firstDigit = digitCount;
                                    digitCount++;
                                    lastDigit = digitCount;
                                    break;
                                case '.':
                                    if (decimalPos < 0)
                                        decimalPos = digitCount;
                                    break;
                                case ',':
                                    if (digitCount > 0 && decimalPos < 0)
                                    {
                                        if (thousandPos >= 0)
                                        {
                                            if (thousandPos == digitCount)
                                            {
                                                thousandCount++;
                                                break;
                                            }
                                            thousandSeps = true;
                                        }
                                        thousandPos = digitCount;
                                        thousandCount = 1;
                                    }
                                    break;
                                case '%':
                                    scaleAdjust += 2;
                                    break;
                                case '\x2030':
                                    scaleAdjust += 3;
                                    break;
                                case '\'':
                                case '"':
                                    while (pFormat[src] != 0 && pFormat[src++] != ch)
                                        ;
                                    break;
                                case '\\':
                                    if (pFormat[src] != 0)
                                        src++;
                                    break;
                                case 'E':
                                case 'e':
                                    if (pFormat[src] == '0' || ((pFormat[src] == '+' || pFormat[src] == '-') && pFormat[src + 1] == '0'))
                                    {
                                        while (pFormat[++src] == '0')
                                            ;
                                        scientific = true;
                                    }
                                    break;
                            }
                        }
                    }

                    if (decimalPos < 0)
                        decimalPos = digitCount;

                    if (thousandPos >= 0)
                    {
                        if (thousandPos == decimalPos)
                            scaleAdjust -= thousandCount * 3;
                        else
                            thousandSeps = true;
                    }

                    if (dig[0] != 0)
                    {
                        number.scale += scaleAdjust;
                        int pos = scientific ? digitCount : number.scale + digitCount - decimalPos;
                        RoundNumber(ref number, pos);
                        if (dig[0] == 0)
                        {
                            src = FindSection(format, 2);
                            if (src != section)
                            {
                                section = src;
                                continue;
                            }
                        }
                    }
                    else
                    {
                        number.sign = false;   // We need to format -0 without the sign set.
                        number.scale = 0;      // Decimals with scale ('0.00') should be rounded.
                    }

                    break;
                }

                firstDigit = firstDigit < decimalPos ? decimalPos - firstDigit : 0;
                lastDigit = lastDigit > decimalPos ? decimalPos - lastDigit : 0;
                if (scientific)
                {
                    digPos = decimalPos;
                    adjust = 0;
                }
                else
                {
                    digPos = number.scale > decimalPos ? number.scale : decimalPos;
                    adjust = number.scale - decimalPos;
                }
                src = section;

                // Adjust can be negative, so we make this an int instead of an unsigned int.
                // Adjust represents the number of characters over the formatting e.g. format string is "0000" and you are trying to
                // format 100000 (6 digits). Means adjust will be 2. On the other hand if you are trying to format 10 adjust will be
                // -2 and we'll need to fixup these digits with 0 padding if we have 0 formatting as in this example.
                int[] thousandsSepPos = new int[4];
                int thousandsSepCtr = -1;

                if (thousandSeps)
                {
                    // We need to precompute this outside the number formatting loop
                    if (info.NumberGroupSeparator.Length > 0)
                    {
                        // We need this array to figure out where to insert the thousands separator. We would have to traverse the string
                        // backwards. PIC formatting always traverses forwards. These indices are precomputed to tell us where to insert
                        // the thousands separator so we can get away with traversing forwards. Note we only have to compute up to digPos.
                        // The max is not bound since you can have formatting strings of the form "000,000..", and this
                        // should handle that case too.

                        int[] groupDigits = info.NumberGroupSizes;

                        int groupSizeIndex = 0;     // Index into the groupDigits array.
                        int groupTotalSizeCount = 0;
                        int groupSizeLen = groupDigits.Length;    // The length of groupDigits array.
                        if (groupSizeLen != 0)
                            groupTotalSizeCount = groupDigits[groupSizeIndex];   // The current running total of group size.
                        int groupSize = groupTotalSizeCount;

                        int totalDigits = digPos + ((adjust < 0) ? adjust : 0); // Actual number of digits in o/p
                        int numDigits = (firstDigit > totalDigits) ? firstDigit : totalDigits;
                        while (numDigits > groupTotalSizeCount)
                        {
                            if (groupSize == 0)
                                break;
                            ++thousandsSepCtr;
                            if (thousandsSepCtr >= thousandsSepPos.Length)
                                Array.Resize(ref thousandsSepPos, thousandsSepPos.Length * 2);

                            thousandsSepPos[thousandsSepCtr] = groupTotalSizeCount;
                            if (groupSizeIndex < groupSizeLen - 1)
                            {
                                groupSizeIndex++;
                                groupSize = groupDigits[groupSizeIndex];
                            }
                            groupTotalSizeCount += groupSize;
                        }
                    }
                }

                StringBuilder sb = new StringBuilder(MIN_SB_BUFFER_SIZE);

                if (number.sign && section == 0)
                    sb.Append(info.NegativeSign);

                bool decimalWritten = false;

                fixed (char* pFormat = format)
                {
                    char* cur = dig;

                    while ((ch = pFormat[src++]) != 0 && ch != ';')
                    {
                        if (adjust > 0)
                        {
                            switch (ch)
                            {
                                case '#':
                                case '0':
                                case '.':
                                    while (adjust > 0)
                                    {
                                        // digPos will be one greater than thousandsSepPos[thousandsSepCtr] since we are at
                                        // the character after which the groupSeparator needs to be appended.
                                        sb.Append(*cur != 0 ? *cur++ : '0');
                                        if (thousandSeps && digPos > 1 && thousandsSepCtr >= 0)
                                        {
                                            if (digPos == thousandsSepPos[thousandsSepCtr] + 1)
                                            {
                                                sb.Append(info.NumberGroupSeparator);
                                                thousandsSepCtr--;
                                            }
                                        }
                                        digPos--;
                                        adjust--;
                                    }
                                    break;
                            }
                        }

                        switch (ch)
                        {
                            case '#':
                            case '0':
                                {
                                    if (adjust < 0)
                                    {
                                        adjust++;
                                        ch = digPos <= firstDigit ? '0' : '\0';
                                    }
                                    else
                                    {
                                        ch = *cur != 0 ? *cur++ : digPos > lastDigit ? '0' : '\0';
                                    }
                                    if (ch != 0)
                                    {
                                        sb.Append(ch);
                                        if (thousandSeps && digPos > 1 && thousandsSepCtr >= 0)
                                        {
                                            if (digPos == thousandsSepPos[thousandsSepCtr] + 1)
                                            {
                                                sb.Append(info.NumberGroupSeparator);
                                                thousandsSepCtr--;
                                            }
                                        }
                                    }

                                    digPos--;
                                    break;
                                }
                            case '.':
                                {
                                    if (digPos != 0 || decimalWritten)
                                    {
                                        // For compatibility, don't echo repeated decimals
                                        break;
                                    }
                                    // If the format has trailing zeros or the format has a decimal and digits remain
                                    if (lastDigit < 0 || (decimalPos < digitCount && *cur != 0))
                                    {
                                        sb.Append(info.NumberDecimalSeparator);
                                        decimalWritten = true;
                                    }
                                    break;
                                }
                            case '\x2030':
                                sb.Append(info.PerMilleSymbol);
                                break;
                            case '%':
                                sb.Append(info.PercentSymbol);
                                break;
                            case ',':
                                break;
                            case '\'':
                            case '"':
                                while (pFormat[src] != 0 && pFormat[src] != ch)
                                    sb.Append(pFormat[src++]);
                                if (pFormat[src] != 0)
                                    src++;
                                break;
                            case '\\':
                                if (pFormat[src] != 0)
                                    sb.Append(pFormat[src++]);
                                break;
                            case 'E':
                            case 'e':
                                {
                                    bool positiveSign = false;
                                    int i = 0;
                                    if (scientific)
                                    {
                                        if (pFormat[src] == '0')
                                        {
                                            // Handles E0, which should format the same as E-0
                                            i++;
                                        }
                                        else if (pFormat[src] == '+' && pFormat[src + 1] == '0')
                                        {
                                            // Handles E+0
                                            positiveSign = true;
                                        }
                                        else if (pFormat[src] == '-' && pFormat[src + 1] == '0')
                                        {
                                            // Handles E-0
                                            // Do nothing, this is just a place holder s.t. we don't break out of the loop.
                                        }
                                        else
                                        {
                                            sb.Append(ch);
                                            break;
                                        }

                                        while (pFormat[++src] == '0')
                                            i++;
                                        if (i > 10)
                                            i = 10;

                                        int exp = dig[0] == 0 ? 0 : number.scale - decimalPos;
                                        FormatExponent(sb, info, exp, ch, i, positiveSign);
                                        scientific = false;
                                    }
                                    else
                                    {
                                        sb.Append(ch); // Copy E or e to output
                                        if (pFormat[src] == '+' || pFormat[src] == '-')
                                            sb.Append(pFormat[src++]);
                                        while (pFormat[src] == '0')
                                            sb.Append(pFormat[src++]);
                                    }
                                    break;
                                }
                            default:
                                sb.Append(ch);
                                break;
                        }
                    }
                }

                return sb.ToString();
            }
        }