System.Xml.Xsl.Runtime.NumberFormatter.ConvertToDecimal C# (CSharp) Method

ConvertToDecimal() private static method

private static ConvertToDecimal ( double val, int minLen, char zero, string groupSeparator, int groupSize ) : string
val double
minLen int
zero char
groupSeparator string
groupSize int
return string
        private static string ConvertToDecimal(double val, int minLen, char zero, string groupSeparator, int groupSize) {
            Debug.Assert(val >= 0 && val == Math.Round(val), "ConvertToArabic operates on non-negative integer numbers only");
            string str = XPathConvert.DoubleToString(val);
            int  shift = zero - '0';

            // Figure out new string length without separators
            int oldLen = str.Length;
            int newLen = Math.Max(oldLen, minLen);

            // Calculate length of string with separators
            if (groupSize != 0) {
                Debug.Assert(groupSeparator.Length == 1);
                checked { newLen += (newLen - 1) / groupSize; }
            }

            // If the new number of characters equals the old one, no changes need to be made
            if (newLen == oldLen && shift == 0) {
                return str;
            }

            // If grouping is not needed, add zero padding only
            if (groupSize == 0 && shift == 0) {
                return str.PadLeft(newLen, zero);
            }

            // Add both grouping separators and zero padding to the string representation of a number
        #if true
            unsafe {
                char *result = stackalloc char[newLen];
                char separator = (groupSeparator.Length > 0) ? groupSeparator[0] : ' ';

                fixed (char *pin = str) {
                    char *pOldEnd = pin + oldLen - 1;
                    char *pNewEnd = result + newLen - 1;
                    int cnt = groupSize;

                    while (true) {
                        // Move digit to its new location (zero if we've run out of digits)
                        *pNewEnd-- = (pOldEnd >= pin) ? (char)(*pOldEnd-- + shift) : zero;
                        if (pNewEnd < result) {
                            break;
                        }
                        if (/*groupSize > 0 && */--cnt == 0) {
                            // Every groupSize digits insert the separator
                            *pNewEnd-- = separator;
                            cnt = groupSize;
                            Debug.Assert(pNewEnd >= result, "Separator cannot be the first character");
                        }
                    }
                }
                return new string(result, 0, newLen);
            }
        #else
            // Safe version is about 20% slower after NGEN
            char[] result = new char[newLen];
            char separator = (groupSeparator.Length > 0) ? groupSeparator[0] : ' ';

            int oldEnd = oldLen - 1;
            int newEnd = newLen - 1;
            int cnt = groupSize;

            while (true) {
                // Move digit to its new location (zero if we've run out of digits)
                result[newEnd--] = (oldEnd >= 0) ? (char)(str[oldEnd--] + shift) : zero;
                if (newEnd < 0) {
                    break;
                }
                if (/*groupSize > 0 && */--cnt == 0) {
                    // Every groupSize digits insert the separator
                    result[newEnd--] = separator;
                    cnt = groupSize;
                    Debug.Assert(newEnd >= 0, "Separator cannot be the first character");
                }
            }
            return new string(result, 0, newLen);
        #endif
        }
    }