解决方案 »

  1.   

    试一试 Decimal。  128bit
      

  2.   

    Decimal试试这个,精度比double高很多,再不行就自己写个数据类型
      

  3.   

    怎么自己写个数据类型?我的想法是把小数点后的数字全部转换成string类型,再输出。但是不太会。请指教。我还是新手。
      

  4.   

    反序列化一下,然后针对对象做可以看下Newtonsoft.Json
      

  5.   

    double只有十几位有效数字,你就算是使用牛顿迭代法或者二分法,又怎样能够得到20位有效数字?请说出一个靠谱的计算算法来。
      

  6.   

    都算你说string能表达10000位有效数字,那么你是如何用牛顿迭代法来得到20位精度的数字呢?完全看不出关系啊?需要你明确说明你的算法。
      

  7.   

    http://download.csdn.net/detail/johnliuyuan/8411515  资源中实现了高精度的浮点运算,不过是C++的,你可以参考一下
      

  8.   

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;namespace ConsoleApplication1
    {
        class Program
        {
            static void swap(ref string s1, ref string s2)
            {
                string tmp = s1;
                s1 = s2;
                s2 = tmp;
            }        static int cmp(string s1,string s2)
            {
                if (s1.Length > s2.Length) return 1;
                else if (s1.Length < s2.Length) return -1;
                return string.Compare(s1, s2);
            }        /*模拟手算减法*/
            static string minus(string s1,string s2)
            {
                int sign = 1;
                if (s1[0] == '-')
                {
                    if (s2[0] == '-')
                    {
                        s1 = s1.Remove(0, 1);
                        s2 = s2.Remove(0, 1);
                        swap(ref s1, ref s2);
                    }
                    else
                        return add(s1, '-'+s2);
                }
                else if (s2[0] == '-')
                    return add(s1, s2.Remove(0,1));            string res="";
                int c = cmp(s1,s2);
                if (c == 0)
                    return "0";
                else if (c<0)
                {
                    swap(ref s1, ref s2);
                    sign = -1;
                }
                int bit,carry=0;
                int n1, n2;
                int i, j;
                for (i = s1.Length-1,j = s2.Length-1; j >= 0;i--,j--)
                {
                    n1 = s1[i] - '0' - carry;
                    n2 = s2[j] - '0';
                    carry = 0;
                    if (n1 < n2)
                    {
                        n1 += 10;
                        carry=1;
                    }
                    bit = n1 - n2;
                    res = (char)(bit + '0') + res;
                }
                if (i > 0 && carry == 1)
                {
                    while (s1[i] == '0')
                    {
                        res = '9' + res;
                        i--;
                    }
                }
                if (i>=0) res = s1.Substring(0, i) + (char)(s1[i] - carry) + res;
                for (i = 0; res[i] == '0' && i<res.Length-1; i++) ;
                res = res.Remove(0, i);
                if (sign == -1)
                    res = '-' + res;
                return res;
            }        /*模拟手算加法*/
            static string add(string s1,string s2)
            {
                int sign = 1;
                if (s1[0]=='-')
                {
                    if (s2[0]=='-')
                    {
                        s1 = s1.Remove(0, 1);
                        s2 = s2.Remove(0, 1);
                        sign = -1;
                    }
                    else
                        return minus(s2, s1.Remove(0, 1));
                }
                else if (s2[0]=='-')
                    return minus(s1, s2);            string res="";
                int bit, addover = 0;
                if (s1.Length < s2.Length)
                    swap(ref s1, ref s2);
                int i,j;
                for (i=s1.Length-1,j=s2.Length-1;j>=0;i--,j--)
                {
                    bit = ((s1[i] - '0') + (s2[j] - '0') + addover) % 10;
                    addover = ((s1[i] - '0') + (s2[j] - '0') + addover) / 10;
                    res = (char)(bit + '0') + res;
                }
                for (;i>=0;i--)
                {
                    bit = ((s1[i] - '0') + addover) % 10;
                    addover = ((s1[i] - '0') + addover) / 10;
                    res = (char)(bit + '0') + res;
                }
                if (addover>0)
                    res = (char)(addover + '0') + res;
                if (sign == -1)
                    return '-'+res;
                else
                    return res;
            }        /*模拟手算乘法*/
            static string multiply(string s1,string s2)
            {
                int sign1 = 1, sign2 = 2;
                if (s1[0] == '-')
                {
                    sign1 = -1;
                    s1 = s1.Remove(0, 1);
                }
                if (s2[0] == '-')
                {
                    sign2 = -1;
                    s2 = s2.Remove(0, 1);
                }
                string res = "0";  
                for (int i=s1.Length-1;i>=0;i--)
                {
                    int bit, addover = 0;
                    string tres = "";
                    for (int j=s2.Length-1;j>=0;j--)
                    {
                        bit = ((s1[i] - '0') * (s2[j] - '0') + addover) % 10;
                        addover = ((s1[i] - '0') * (s2[j] - '0') + addover) / 10;
                        tres = (char)(bit + '0') + tres;
                    }
                    if (addover > 0)
                        tres = (char)(addover + '0') + tres;
                    for (int k = 1; k < s1.Length - i; ++k)
                        tres = tres + '0';
                    res = add(res, tres);
                }
                if (sign1 * sign2 == -1)
                    res = '-' + res;
                return res;        }        /*模拟手算除法*/
            static string divide(string s1,string s2)
            {
                int sign1 = 1, sign2 = 2;
                if (s1[0] == '-')
                {
                    sign1 = -1;
                    s1 = s1.Remove(0, 1);
                }
                if (s2[0] == '-')
                {
                    sign2 = -1;
                    s2 = s2.Remove(0, 1);
                }
                int c = cmp(s1, s2);
                if (c < 0)
                    return "0";
                else if (c == 0)
                    return "1";            string res = "";
                string cur = s1.Substring(0,s2.Length-1);
                for (int i=s2.Length-1;i<s1.Length;++i)
                {
                    if (cur == "0") cur = "";
                    cur = cur + s1[i];
                    for (int k=9;k>=0;--k)
                    {
                        string tres = "" + (char)(k + '0');
                        string tmp = multiply(s2, tres);
                        if (cmp(cur,tmp)>=0)
                        {
                            cur = minus(cur, tmp);
                            res = res + tres;
                            break;
                        }
                    }
                    
                }
                int x;
                for (x = 0; res[x] == '0' && x < res.Length - 1; x++) ;
                res = res.Remove(0, x);
                if (sign1 * sign2 == -1)
                    res = '-' + res;
                return res;
            }
            
            /* 求解根号2的50次方,即把运算转换成高精度整数加减乘除 */
            static void Main(string[] args)
            {
                /* 构造x2=2*10^50次方作为初值,同时构造s2=2*10^50 */
                string x2="2", s2="2";
                for (int i=0;i<100;i++)
                {
                    if (i%2==0) x2=x2+'0';
                    s2=s2+'0';
                }
                string x1="0";
                while (cmp(x1,x2)!=0)
                {
                    x1=x2;
                    x2=minus(x1,divide(minus(multiply(x1,x1),s2),multiply("2",x1)));    /* 牛顿迭代公式Xn+1=Xn-f(Xn)/f'(Xn),f(X)=X*X-2*10^50 */
                    Console.WriteLine(x1.Insert(1,"."));
                }
                Console.Read();
            }
        }
    }