C#效率极子 - 精益求精
自动化+性能优化

首先声明,.net自带的ToString方法很好用,也很强大。但我个人基本上只用过最简单的方式,即无参的ToString()函数。关注性能的你也许会发现ToString是个高消费品,但是很多时候又不得不用。想要用得更舒心,那就自食其力吧。

我们知道普通的十进制转换就是一个对10求余取模的循环,而求余取模对于CPU相对于其他运算来说是一件吃力的事情。而对于常数的求余取模一般都可以转换为乘法运算。思路有了,开始敲代码,经过大量Copy、Paste,终于将byte,sbyte,short,ushort,int,uint,long,ulong各个击破。

        public const uint div10_16Mul = ((1 << 19) + 9) / 10;
        public const int div10_16Shift = 19;
        public const ulong div10000Mul = ((1L << 45) + 9999) / 10000;
        public const int div10000Shift = 45;
        public const ulong div100000000Mul = ((1L << 58) + 99999999) / 100000000;
        public const int div100000000Shift = 58;
        public unsafe static string toString(this byte value)
        {
            if (value >= 100)
            {
                char* chars = stackalloc char[4];
                int value10 = (value * (int)showjim.sys.number.div10_16Mul) >> showjim.sys.number.div10_16Shift;
                chars[2] = (char)((value - value10 * 10) + '0');
                int value100 = (value10 * (int)showjim.sys.number.div10_16Mul) >> showjim.sys.number.div10_16Shift;
                *(int*)chars = ((value10 - value100 * 10) << 16) | value100 | 0x300030;
                return new string(chars, 0, 3);
            }
            else if (value >= 10)
            {
                char* chars = stackalloc char[2];
                int value10 = (value * (int)showjim.sys.number.div10_16Mul) >> showjim.sys.number.div10_16Shift;
                *(int*)chars = ((value - value10 * 10) << 16) | value10 | 0x300030;
                return new string(chars, 0, 2);
            }
            return new string((char)(value + '0'), 1);
        }
        public unsafe static string toString(this sbyte value)
        {
            if (value >= 0)
            {
                if (value >= 100)
                {
                    char* chars = stackalloc char[3];
                    value -= 100;
                    *chars = '1';
                    int value10 = (value * (int)showjim.sys.number.div10_16Mul) >> showjim.sys.number.div10_16Shift;
                    *(int*)(chars + 1) = ((value - value10 * 10) << 16) | value10 | 0x300030;
                    return new string(chars, 0, 3);
                }
                else if (value >= 10)
                {
                    char* chars = stackalloc char[2];
                    int value10 = (value * (int)showjim.sys.number.div10_16Mul) >> showjim.sys.number.div10_16Shift;
                    *(int*)chars = ((value - value10 * 10) << 16) | value10 | 0x300030;
                    return new string(chars, 0, 2);
                }
                return new string((char)(value + '0'), 1);
            }
            else
            {
                int value32 = -value;
                if (value32 >= 100)
                {
                    char* chars = stackalloc char[4];
                    value32 -= 100;
                    *(int*)chars = '-' + ('1' << 16);
                    int value10 = (value32 * (int)showjim.sys.number.div10_16Mul) >> showjim.sys.number.div10_16Shift;
                    *(int*)(chars + 2) = ((value32 - value10 * 10) << 16) | value10 | 0x300030;
                    return new string(chars, 0, 4);
                }
                else if (value32 >= 10)
                {
                    char* chars = stackalloc char[3];
                    *chars = '-';
                    int value10 = (value32 * (int)showjim.sys.number.div10_16Mul) >> showjim.sys.number.div10_16Shift;
                    *(int*)(chars + 1) = ((value32 - value10 * 10) << 16) | value10 | 0x300030;
                    return new string(chars, 0, 3);
                }
                else
                {
                    char* chars = stackalloc char[2];
                    *(int*)chars = '-' + ((value32 + '0') << 16);
                    return new string(chars, 0, 2);
                }
            }
        }
        public unsafe static string toString(this ushort value)
        {
            if (value >= 10000)
            {
                char* chars = stackalloc char[5];
                int value10 = (int)((uint)(value * showjim.sys.number.div10_16Mul) >> showjim.sys.number.div10_16Shift);
                int value100 = (value10 * (int)showjim.sys.number.div10_16Mul) >> showjim.sys.number.div10_16Shift;
                *(int*)(chars + 3) = ((value - value10 * 10) << 16) | (value10 - value100 * 10) | 0x300030;
                value10 = (value100 * (int)showjim.sys.number.div10_16Mul) >> showjim.sys.number.div10_16Shift;
                value = (ushort)((value10 * showjim.sys.number.div10_16Mul) >> showjim.sys.number.div10_16Shift);
                *(int*)(chars + 1) = ((value100 - value10 * 10) << 16) | (value10 - value * 10) | 0x300030;
                *chars = (char)(value + '0');
                return new string(chars, 0, 5);
            }
            else if (value >= 100)
            {
                char* chars = stackalloc char[4];
                int value10 = (value * (int)showjim.sys.number.div10_16Mul) >> showjim.sys.number.div10_16Shift;
                if (value >= 1000)
                {
                    int value100 = (value10 * (int)showjim.sys.number.div10_16Mul) >> showjim.sys.number.div10_16Shift;
                    *(int*)(chars + 2) = ((value - value10 * 10) << 16) | (value10 - value100 * 10) | 0x300030;
                    value10 = (value100 * (int)showjim.sys.number.div10_16Mul) >> showjim.sys.number.div10_16Shift;
                    *(int*)chars = ((value100 - value10 * 10) << 16) | value10 | 0x300030;
                    return new string(chars, 0, 4);
                }
                else
                {
                    chars[2] = (char)((value - value10 * 10) + '0');
                    int value100 = (value10 * (int)showjim.sys.number.div10_16Mul) >> showjim.sys.number.div10_16Shift;
                    *(int*)chars = ((value10 - value100 * 10) << 16) | value100 | 0x300030;
                    return new string(chars, 0, 3);
                }
            }
            else if (value >= 10)
            {
                char* chars = stackalloc char[2];
                int value10 = (value * (int)showjim.sys.number.div10_16Mul) >> showjim.sys.number.div10_16Shift;
                *(int*)chars = ((value - value10 * 10) << 16) | value10 | 0x300030;
                return new string(chars, 0, 2);
            }
            return new string((char)(value + '0'), 1);
        }
        public unsafe static string toString(this short value)
        {
            if (value >= 0) return toString((ushort)value);
            int value32 = -value;
            if (value32 >= 10000)
            {
                char* chars = stackalloc char[6];
                int value10 = (int)((uint)(value32 * showjim.sys.number.div10_16Mul) >> showjim.sys.number.div10_16Shift);
                int value100 = (value10 * (int)showjim.sys.number.div10_16Mul) >> showjim.sys.number.div10_16Shift;
                *(int*)(chars + 4) = ((value32 - value10 * 10) << 16) | (value10 - value100 * 10) | 0x300030;
                value10 = (value100 * (int)showjim.sys.number.div10_16Mul) >> showjim.sys.number.div10_16Shift;
                value32 = (value10 * (int)showjim.sys.number.div10_16Mul) >> showjim.sys.number.div10_16Shift;
                *(int*)(chars + 2) = ((value100 - value10 * 10) << 16) | (value10 - value32 * 10) | 0x300030;
                *(int*)chars = '-' + ((value32 + '0') << 16);
                return new string(chars, 0, 6);
            }
            else if (value32 >= 100)
            {
                if (value32 >= 1000)
                {
                    char* chars = stackalloc char[5];
                    *chars = '-';
                    int value10 = (value32 * (int)showjim.sys.number.div10_16Mul) >> showjim.sys.number.div10_16Shift;
                    int value100 = (value10 * (int)showjim.sys.number.div10_16Mul) >> showjim.sys.number.div10_16Shift;
                    *(int*)(chars + 3) = ((value32 - value10 * 10) << 16) | (value10 - value100 * 10) | 0x300030;
                    value10 = (value100 * (int)showjim.sys.number.div10_16Mul) >> showjim.sys.number.div10_16Shift;
                    *(int*)(chars + 1) = ((value100 - value10 * 10) << 16) | value10 | 0x300030;
                    return new string(chars, 0, 5);
                }
                else
                {
                    char* chars = stackalloc char[4];
                    int value10 = (value32 * (int)showjim.sys.number.div10_16Mul) >> showjim.sys.number.div10_16Shift;
                    int value100 = (value10 * (int)showjim.sys.number.div10_16Mul) >> showjim.sys.number.div10_16Shift;
                    *(int*)(chars + 2) = ((value32 - value10 * 10) << 16) | (value10 - value100 * 10) | 0x300030;
                    *(int*)chars = '-' + ((value100 + '0') << 16);
                    return new string(chars, 0, 4);
                }
            }
            else if (value32 >= 10)
            {
                char* chars = stackalloc char[3];
                *chars = '-';
                int value10 = (value32 * (int)showjim.sys.number.div10_16Mul) >> showjim.sys.number.div10_16Shift;
                *(int*)(chars + 1) = ((value32 - value10 * 10) << 16) | value10 | 0x300030;
                return new string(chars, 0, 3);
            }
            else
            {
                char* chars = stackalloc char[2];
                *(int*)chars = '-' + ((value32 + '0') << 16);
                return new string(chars, 0, 2);
            }
        }
        public unsafe static string toString(this uint value)
        {
            if (value >= 100000000)
            {
                char* chars = stackalloc char[10];
                uint value100000000 = (uint)((value * (ulong)showjim.sys.number.div100000000Mul) >> showjim.sys.number.div100000000Shift);
                value -= value100000000 * 100000000;
                uint value10000 = (uint)((value * showjim.sys.number.div10000Mul) >> showjim.sys.number.div10000Shift);
                ToString(value10000, chars + 2);
                ToString(value - value10000 * 10000, chars + 6);
                if (value100000000 >= 10)
                {
                    value10000 = (value100000000 * showjim.sys.number.div10_16Mul) >> showjim.sys.number.div10_16Shift;
                    *(uint*)chars = ((value100000000 - value10000 * 10) << 16) | value10000 | 0x300030U;
                    return new string(chars, 0, 10);
                }
                *++chars = (char)(value100000000 + '0');
                return new string(chars, 0, 9);
            }
            return ToString99999999(value);
        }
        private unsafe static string ToString99999999(uint value)
        {
            if (value >= 10000)
            {
                char* chars = stackalloc char[8];
                uint value10000 = (uint)((value * showjim.sys.number.div10000Mul) >> showjim.sys.number.div10000Shift);
                if (value10000 >= 100)
                {
                    uint value10 = (value10000 * showjim.sys.number.div10_16Mul) >> showjim.sys.number.div10_16Shift;
                    if (value10000 >= 1000)
                    {
                        ToString(value - value10000 * 10000, chars + 4);
                        value = (value10 * showjim.sys.number.div10_16Mul) >> showjim.sys.number.div10_16Shift;
                        *(uint*)(chars + 2) = ((value10000 - value10 * 10) << 16) | (value10 - value * 10) | 0x300030U;
                        value10 = (value * showjim.sys.number.div10_16Mul) >> showjim.sys.number.div10_16Shift;
                        *(uint*)chars = ((value - value10 * 10) << 16) | value10 | 0x300030U;
                        return new string(chars, 0, 8);
                    }
                    else
                    {
                        ToString(value - value10000 * 10000, chars + 3);
                        chars[2] = (char)((value10000 - value10 * 10) + '0');
                        value = (value10 * showjim.sys.number.div10_16Mul) >> showjim.sys.number.div10_16Shift;
                        *(uint*)chars = ((value10 - value * 10) << 16) | value | 0x300030U;
                        return new string(chars, 0, 7);
                    }
                }
                else if (value10000 >= 10)
                {
                    ToString(value - value10000 * 10000, chars + 2);
                    value = (value10000 * showjim.sys.number.div10_16Mul) >> showjim.sys.number.div10_16Shift;
                    *(uint*)chars = ((value10000 - value * 10) << 16) | value | 0x300030U;
                    return new string(chars, 0, 6);
                }
                ToString(value - value10000 * 10000, chars + 1);
                chars[0] = (char)(value10000 + '0');
                return new string(chars, 0, 5);
            }
            else if (value >= 100)
            {
                char* chars = stackalloc char[4];
                uint value10 = (value * showjim.sys.number.div10_16Mul) >> showjim.sys.number.div10_16Shift;
                if (value >= 1000)
                {
                    uint value100 = (value10 * showjim.sys.number.div10_16Mul) >> showjim.sys.number.div10_16Shift;
                    *(uint*)(chars + 2) = ((value - value10 * 10) << 16) | (value10 - value100 * 10) | 0x300030U;
                    value10 = (value100 * showjim.sys.number.div10_16Mul) >> showjim.sys.number.div10_16Shift;
                    *(uint*)chars = ((value100 - value10 * 10) << 16) | value10 | 0x300030U;
                    return new string(chars, 0, 4);
                }
                else
                {
                    chars[2] = (char)((value - value10 * 10) + '0');
                    uint value100 = (value10 * showjim.sys.number.div10_16Mul) >> showjim.sys.number.div10_16Shift;
                    *(uint*)chars = ((value10 - value100 * 10) << 16) | value100 | 0x300030U;
                    return new string(chars, 0, 3);
                }
            }
            else if (value >= 10)
            {
                char* chars = stackalloc char[2];
                uint value10 = (value * showjim.sys.number.div10_16Mul) >> showjim.sys.number.div10_16Shift;
                *(uint*)chars = ((value - value10 * 10) << 16) | value10 | 0x300030U;
                return new string(chars, 0, 2);
            }
            return new string((char)(value + '0'), 1);
        }
        public unsafe static string toString(this int value)
        {
            if (value >= 0) return toString((uint)value);
            uint value32 = (uint)-value;
            if (value32 >= 100000000)
            {
                char* chars = stackalloc char[12];
                uint value100000000 = (uint)((value32 * (ulong)showjim.sys.number.div100000000Mul) >> showjim.sys.number.div100000000Shift);
                value32 -= value100000000 * 100000000;
                uint value10000 = (uint)((value32 * showjim.sys.number.div10000Mul) >> showjim.sys.number.div10000Shift);
                ToString(value10000, chars + 4);
                ToString(value32 - value10000 * 10000, chars + 8);
                if (value100000000 >= 10)
                {
                    value10000 = (value100000000 * showjim.sys.number.div10_16Mul) >> showjim.sys.number.div10_16Shift;
                    *(uint*)(chars + 2) = ((value100000000 - value10000 * 10) << 16) | value10000 | 0x300030U;
                    *++chars = '-';
                    return new string(chars, 0, 11);
                }
                *(uint*)(chars += 2) = '-' + ((value100000000 + '0') << 16);
                return new string(chars, 0, 10);
            }
            return ToString_99999999(value32);
        }
        private unsafe static string ToString_99999999(uint value)
        {
            if (value >= 10000)
            {
                char* chars = stackalloc char[10];
                uint value10000 = (uint)((value * showjim.sys.number.div10000Mul) >> showjim.sys.number.div10000Shift);
                if (value10000 >= 100)
                {
                    uint value10 = (value10000 * showjim.sys.number.div10_16Mul) >> showjim.sys.number.div10_16Shift;
                    if (value10000 >= 1000)
                    {
                        ToString(value - value10000 * 10000, chars + 6);
                        value = (value10 * showjim.sys.number.div10_16Mul) >> showjim.sys.number.div10_16Shift;
                        *(uint*)(chars + 4) = ((value10000 - value10 * 10) << 16) | (value10 - value * 10) | 0x300030U;
                        value10 = (value * showjim.sys.number.div10_16Mul) >> showjim.sys.number.div10_16Shift;
                        *(uint*)(chars + 2) = ((value - value10 * 10) << 16) | value10 | 0x300030U;
                        *++chars = '-';
                        return new string(chars, 0, 9);
                    }
                    else
                    {
                        ToString(value - value10000 * 10000, chars + 4);
                        value = (value10 * showjim.sys.number.div10_16Mul) >> showjim.sys.number.div10_16Shift;
                        *(uint*)(chars + 2) = ((value10000 - value10 * 10) << 16) | (value10 - value * 10) | 0x300030U;
                        *(uint*)chars = '-' + ((value + '0') << 16);
                        return new string(chars, 0, 8);
                    }
                }
                else if (value10000 >= 10)
                {
                    ToString(value - value10000 * 10000, chars + 4);
                    value = (value10000 * showjim.sys.number.div10_16Mul) >> showjim.sys.number.div10_16Shift;
                    *(uint*)(chars + 2) = ((value10000 - value * 10) << 16) | value | 0x300030U;
                    *++chars = '-';
                    return new string(chars, 0, 7);
                }
                ToString(value - value10000 * 10000, chars + 2);
                *(uint*)chars = '-' + ((value10000 + '0') << 16);
                return new string(chars, 0, 6);
            }
            else if (value >= 100)
            {
                if (value >= 1000)
                {
                    char* chars = stackalloc char[6];
                    uint value10 = (value * showjim.sys.number.div10_16Mul) >> showjim.sys.number.div10_16Shift;
                    uint value100 = (value10 * showjim.sys.number.div10_16Mul) >> showjim.sys.number.div10_16Shift;
                    *(uint*)(chars + 4) = ((value - value10 * 10) << 16) | (value10 - value100 * 10) | 0x300030U;
                    value10 = (value100 * showjim.sys.number.div10_16Mul) >> showjim.sys.number.div10_16Shift;
                    *(uint*)(chars + 2) = ((value100 - value10 * 10) << 16) | value10 | 0x300030U;
                    *++chars = '-';
                    return new string(chars, 0, 5);
                }
                else
                {
                    char* chars = stackalloc char[4];
                    uint value10 = (value * showjim.sys.number.div10_16Mul) >> showjim.sys.number.div10_16Shift;
                    uint value100 = (value10 * showjim.sys.number.div10_16Mul) >> showjim.sys.number.div10_16Shift;
                    *(uint*)(chars + 2) = ((value - value10 * 10) << 16) | (value10 - value100 * 10) | 0x300030U;
                    *(uint*)chars = '-' + ((value100 + '0') << 16);
                    return new string(chars, 0, 4);
                }
            }
            else if (value >= 10)
            {
                char* chars = stackalloc char[3];
                *chars = '-';
                uint value10 = (value * showjim.sys.number.div10_16Mul) >> showjim.sys.number.div10_16Shift;
                *(uint*)(chars + 1) = ((value - value10 * 10) << 16) | value10 | 0x300030U;
                return new string(chars, 0, 3);
            }
            else
            {
                char* chars = stackalloc char[2];
                *(uint*)chars = '-' + ((value + '0') << 16);
                return new string(chars, 0, 2);
            }
        }
        private unsafe static void ToString(uint value, char* chars)
        {
            uint value10 = (value * showjim.sys.number.div10_16Mul) >> showjim.sys.number.div10_16Shift;
            uint value100 = (value10 * showjim.sys.number.div10_16Mul) >> showjim.sys.number.div10_16Shift;
            *(uint*)(chars + 2) = ((value - value10 * 10) << 16) | (value10 - value100 * 10) | 0x300030U;
            value10 = (value100 * showjim.sys.number.div10_16Mul) >> showjim.sys.number.div10_16Shift;
            *(uint*)chars = ((value100 - value10 * 10) << 16) | value10 | 0x300030U;
        }
        public unsafe static string toString(this ulong value)
        {
            if (value >= 10000000000000000L)
            {
                char* chars = stackalloc char[20];
                ulong value100000000 = value / 100000000;
                value -= value100000000 * 100000000;
                uint value10000 = (uint)((value * showjim.sys.number.div10000Mul) >> showjim.sys.number.div10000Shift);
                ToString(value10000, chars + 12);
                ToString((uint)value - value10000 * 10000U, chars + 16);
                value = value100000000 / 100000000;
                value100000000 -= value * 100000000;
                value10000 = (uint)((value100000000 * showjim.sys.number.div10000Mul) >> showjim.sys.number.div10000Shift);
                ToString(value10000, chars + 4);
                ToString((uint)value100000000 - value10000 * 10000U, chars + 8);
                uint value32 = (uint)value;
                if (value32 >= 100)
                {
                    value10000 = (value32 * showjim.sys.number.div10_16Mul) >> showjim.sys.number.div10_16Shift;
                    uint value100 = (value10000 * showjim.sys.number.div10_16Mul) >> showjim.sys.number.div10_16Shift;
                    *(uint*)(chars + 2) = ((value32 - value10000 * 10) << 16) | (value10000 - value100 * 10) | 0x300030U;
                    if (value32 >= 1000)
                    {
                        value10000 = (value100 * showjim.sys.number.div10_16Mul) >> showjim.sys.number.div10_16Shift;
                        *(uint*)chars = ((value100 - value10000 * 10) << 16) | value10000 | 0x300030U;
                        return new string(chars, 0, 20);
                    }
                    else
                    {
                        *++chars = (char)(value100 + '0');
                        return new string(chars, 0, 19);
                    }
                }
                else if (value32 >= 10)
                {
                    value10000 = (value32 * showjim.sys.number.div10_16Mul) >> showjim.sys.number.div10_16Shift;
                    *(uint*)(chars += 2) = ((value32 - value10000 * 10) << 16) | value10000 | 0x300030U;
                    return new string(chars, 0, 18);
                }
                *(chars += 3) = (char)(value32 + '0');
                return new string(chars, 0, 17);
            }
            else if (value >= 100000000)
            {
                char* chars = stackalloc char[16];
                ulong value100000000 = value / 100000000;
                value -= value100000000 * 100000000;
                uint value10000 = (uint)((value * showjim.sys.number.div10000Mul) >> showjim.sys.number.div10000Shift);
                ToString(value10000, chars + 8);
                ToString((uint)value - value10000 * 10000U, chars + 12);
                uint value32 = (uint)value100000000;
                if (value32 >= 10000)
                {
                    value10000 = (uint)((value100000000 * showjim.sys.number.div10000Mul) >> showjim.sys.number.div10000Shift);
                    ToString(value32 - value10000 * 10000, chars + 4);
                    if (value10000 >= 100)
                    {
                        value32 = (value10000 * showjim.sys.number.div10_16Mul) >> showjim.sys.number.div10_16Shift;
                        if (value10000 >= 1000)
                        {
                            uint value100 = (value32 * showjim.sys.number.div10_16Mul) >> showjim.sys.number.div10_16Shift;
                            *(uint*)(chars + 2) = ((value10000 - value32 * 10) << 16) | (value32 - value100 * 10) | 0x300030U;
                            value32 = (value100 * showjim.sys.number.div10_16Mul) >> showjim.sys.number.div10_16Shift;
                            *(uint*)chars = ((value100 - value32 * 10) << 16) | value32 | 0x300030U;
                            return new string(chars, 0, 16);
                        }
                        else
                        {
                            chars[3] = (char)((value10000 - value32 * 10) + '0');
                            uint value100 = (value32 * showjim.sys.number.div10_16Mul) >> showjim.sys.number.div10_16Shift;
                            *(uint*)(chars += 1) = ((value32 - value100 * 10) << 16) | value100 | 0x300030U;
                            return new string(chars, 0, 15);
                        }
                    }
                    else if (value10000 >= 10)
                    {
                        value32 = (value10000 * showjim.sys.number.div10_16Mul) >> showjim.sys.number.div10_16Shift;
                        *(uint*)(chars += 2) = ((value10000 - value32 * 10) << 16) | value32 | 0x300030U;
                        return new string(chars, 0, 14);
                    }
                    *(chars += 3) = (char)(value10000 + '0');
                    return new string(chars, 0, 13);
                }
                else if (value32 >= 100)
                {
                    value10000 = (value32 * showjim.sys.number.div10_16Mul) >> showjim.sys.number.div10_16Shift;
                    if (value32 >= 1000)
                    {
                        uint value100 = (value10000 * showjim.sys.number.div10_16Mul) >> showjim.sys.number.div10_16Shift;
                        *(uint*)(chars + 6) = ((value32 - value10000 * 10) << 16) | (value10000 - value100 * 10) | 0x300030U;
                        value10000 = (value100 * showjim.sys.number.div10_16Mul) >> showjim.sys.number.div10_16Shift;
                        *(uint*)(chars += 4) = ((value100 - value10000 * 10) << 16) | value10000 | 0x300030U;
                        return new string(chars, 0, 12);
                    }
                    else
                    {
                        chars[7] = (char)((value32 - value10000 * 10) + '0');
                        uint value100 = (value10000 * showjim.sys.number.div10_16Mul) >> showjim.sys.number.div10_16Shift;
                        *(uint*)(chars += 5) = ((value10000 - value100 * 10) << 16) | value100 | 0x300030U;
                        return new string(chars, 0, 11);
                    }
                }
                else if (value32 >= 10)
                {
                    value10000 = (value32 * showjim.sys.number.div10_16Mul) >> showjim.sys.number.div10_16Shift;
                    *(uint*)(chars += 6) = ((value32 - value10000 * 10) << 16) | value10000 | 0x300030U;
                    return new string(chars, 0, 10);
                }
                *(chars += 7) = (char)(value32 + '0');
                return new string(chars, 0, 9);
            }
            return ToString99999999((uint)value);
        }
        public unsafe static string toString(this long value)
        {
            if (value >= 0) return toString((ulong)value);
            ulong value64 = (ulong)-value;
            if (value64 >= 10000000000000000L)
            {
                char* chars = stackalloc char[22];
                ulong value100000000 = value64 / 100000000;
                value64 -= value100000000 * 100000000;
                uint value10000 = (uint)((value64 * showjim.sys.number.div10000Mul) >> showjim.sys.number.div10000Shift);
                ToString(value10000, chars + 14);
                ToString((uint)value64 - value10000 * 10000U, chars + 18);
                value64 = value100000000 / 100000000;
                value100000000 -= value64 * 100000000;
                value10000 = (uint)((value100000000 * showjim.sys.number.div10000Mul) >> showjim.sys.number.div10000Shift);
                ToString(value10000, chars + 6);
                ToString((uint)value100000000 - value10000 * 10000U, chars + 10);
                uint value32 = (uint)value64;
                if (value32 >= 100)
                {
                    value10000 = (value32 * showjim.sys.number.div10_16Mul) >> showjim.sys.number.div10_16Shift;
                    uint value100 = (value10000 * showjim.sys.number.div10_16Mul) >> showjim.sys.number.div10_16Shift;
                    *(uint*)(chars + 4) = ((value32 - value10000 * 10) << 16) | (value10000 - value100 * 10) | 0x300030U;
                    if (value32 >= 1000)
                    {
                        value10000 = (value100 * showjim.sys.number.div10_16Mul) >> showjim.sys.number.div10_16Shift;
                        *(uint*)(chars + 2) = ((value100 - value10000 * 10) << 16) | value10000 | 0x300030U;
                        *++chars = '-';
                        return new string(chars, 0, 21);
                    }
                    else
                    {
                        *(uint*)(chars += 2) = '-' + ((value100 + '0') << 16);
                        return new string(chars, 0, 20);
                    }
                }
                else if (value32 >= 10)
                {
                    value10000 = (value32 * showjim.sys.number.div10_16Mul) >> showjim.sys.number.div10_16Shift;
                    *(uint*)(chars + 4) = ((value32 - value10000 * 10) << 16) | value10000 | 0x300030U;
                    *(chars += 3) = '-';
                    return new string(chars, 0, 19);
                }
                *(uint*)(chars += 4) = '-' + ((value32 + '0') << 16);
                return new string(chars, 0, 18);
            }
            else if (value64 >= 100000000)
            {
                char* chars = stackalloc char[18];
                ulong value100000000 = value64 / 100000000;
                value64 -= value100000000 * 100000000;
                uint value10000 = (uint)((value64 * showjim.sys.number.div10000Mul) >> showjim.sys.number.div10000Shift);
                ToString(value10000, chars + 10);
                ToString((uint)value64 - value10000 * 10000U, chars + 14);
                uint value32 = (uint)value100000000;
                if (value32 >= 10000)
                {
                    value10000 = (uint)((value100000000 * showjim.sys.number.div10000Mul) >> showjim.sys.number.div10000Shift);
                    ToString(value32 - value10000 * 10000, chars + 6);
                    if (value10000 >= 100)
                    {
                        value32 = (value10000 * showjim.sys.number.div10_16Mul) >> showjim.sys.number.div10_16Shift;
                        uint value100 = (value32 * showjim.sys.number.div10_16Mul) >> showjim.sys.number.div10_16Shift;
                        *(uint*)(chars + 4) = ((value10000 - value32 * 10) << 16) | (value32 - value100 * 10) | 0x300030U;
                        if (value10000 >= 1000)
                        {
                            value32 = (value100 * showjim.sys.number.div10_16Mul) >> showjim.sys.number.div10_16Shift;
                            *(uint*)(chars + 2) = ((value100 - value32 * 10) << 16) | value32 | 0x300030U;
                            *++chars = '-';
                            return new string(chars, 0, 17);
                        }
                        else
                        {
                            *(uint*)(chars += 2) = '-' + ((value100 + '0') << 16);
                            return new string(chars, 0, 16);
                        }
                    }
                    else if (value10000 >= 10)
                    {
                        value32 = (value10000 * showjim.sys.number.div10_16Mul) >> showjim.sys.number.div10_16Shift;
                        *(uint*)(chars + 4) = ((value10000 - value32 * 10) << 16) | value32 | 0x300030U;
                        *(chars += 3) = '-';
                        return new string(chars, 0, 15);
                    }
                    *(uint*)(chars += 4) = '-' + ((value10000 + '0') << 16);
                    return new string(chars, 0, 14);
                }
                else if (value32 >= 100)
                {
                    value10000 = (value32 * showjim.sys.number.div10_16Mul) >> showjim.sys.number.div10_16Shift;
                    uint value100 = (value10000 * showjim.sys.number.div10_16Mul) >> showjim.sys.number.div10_16Shift;
                    *(uint*)(chars + 8) = ((value32 - value10000 * 10) << 16) | (value10000 - value100 * 10) | 0x300030U;
                    if (value32 >= 1000)
                    {
                        value10000 = (value100 * showjim.sys.number.div10_16Mul) >> showjim.sys.number.div10_16Shift;
                        *(uint*)(chars + 6) = ((value100 - value10000 * 10) << 16) | value10000 | 0x300030U;
                        *(chars += 5) = '-';
                        return new string(chars, 0, 13);
                    }
                    else
                    {
                        *(uint*)(chars += 6) = '-' + ((value100 + '0') << 16);
                        return new string(chars, 0, 12);
                    }
                }
                else if (value32 >= 10)
                {
                    value10000 = (value32 * showjim.sys.number.div10_16Mul) >> showjim.sys.number.div10_16Shift;
                    *(uint*)(chars + 8) = ((value32 - value10000 * 10) << 16) | value10000 | 0x300030U;
                    *(chars += 7) = '-';
                    return new string(chars, 0, 11);
                }
                *(uint*)(chars += 8) = '-' + ((value32 + '0') << 16);
                return new string(chars, 0, 10);
            }
            return ToString_99999999((uint)value64);
        }

这么多啊?代码又长又乱,算了,不整理它了,反正以后只管调用。Release实测,运行时间降到ToString的1/3,还好,这两小时没有白忙活。

posted on 2012-05-07 14:12  肖进  阅读(555)  评论(2编辑  收藏  举报