双精确整数计算

时间:2015-10-28 12:06:58

标签: c# double precision biginteger

请考虑以下事项:

double x = 87974894654657d;
double y = 76216354532345d;
double a = x * y;
Console.WriteLine(a.ToString("n0"));

BigInteger x1 = new BigInteger(87974894654657);
BigInteger y1 = new BigInteger(76216354532345);
BigInteger a1 = x1 * y1;
Console.WriteLine(a1.ToString("n0"));

输出:

6.705.125.760.945.040.000.000.000.000
6.705.125.760.945.040.955.511.380.665

有没有办法让double正确计算结果? BigIntegers工作正常,但比浮点类型慢得多。我使用的是double而不是long,因为我正在使用非常大的数字。

4 个答案:

答案 0 :(得分:1)

对于您要查找的输出(“极大数字”),您将被限制使用BigInteger或十进制类型。

double x = 87974894654657d;
double y = 76216354532345d;
double a = x * y;
a.Dump();


decimal xd = 87974894654657m;
decimal yd = 76216354532345m;
decimal b = xd * yd;
b.Dump();

输出:

6.70512576094504E+27
6705125760945040955511380665

答案 1 :(得分:1)

试试这段代码:

JOIN

输出为 double d = 6705125760945040955511380665d; Console.WriteLine(d.ToString("n0")); 。双精度值可以表示非常大的值,但它不能精确地表达。这是因为它使用指数,有点像添加10 ^ n。如果您使用小数而不是二进制数并使用4位数,则可以存储5000000这样的数字:6.705.125.760.945.040.000.000.000.000 => 05|06。您可以通过这种方式存储的最大数字是5*10^6 => 99|99,这是一个巨大的数字。但是您无法准确存储数字123456,您只能近似它:99 * 10 ^ 99 => 12|04

如果您需要精确度,请勿使用120000float等浮点数,请改用doubledecimal

答案 2 :(得分:0)

刚刚执行

     Console.WriteLine(DateTime.Now.Second+" "+DateTime.Now.Millisecond+"");
     BigInteger x1 = new BigInteger(87974894654657);
   BigInteger y1 = new BigInteger(76216354532345);
   BigInteger a1 = x1 * y1;
  Console.WriteLine(a1.ToString("n0"));
    Console.WriteLine(DateTime.Now.Second+" "+DateTime.Now.Millisecond+"");

    Console.WriteLine(DateTime.Now.Second+" "+DateTime.Now.Millisecond+"");
    double x = 87974894654657d;
  double y = 76216354532345d;
  double a = x * y;
   Console.WriteLine(a.ToString("n0"));
    Console.WriteLine(DateTime.Now.Second+" "+DateTime.Now.Millisecond+"");

得到了这个结果:

4 216

6,705,125,760,945,040,955,511,380,665

4 216

4 216

6,705,125,760,945,040,000,000,000,000

4 216

没有延迟甚至1毫秒。

答案 3 :(得分:0)

似乎十进制类型比BigInteger类型快一点。

        Stopwatch stopwatch = new Stopwatch();

        stopwatch.Restart();
        double x = 87974894654657d;
        double y = 76216354532345d;
        double a = x * y;
        stopwatch.Stop();
        Console.WriteLine(a.ToString("n0") + " (" + stopwatch.Elapsed.TotalMilliseconds.ToString("0.000") + "ms)");

        stopwatch.Restart();
        BigInteger x1 = new BigInteger(87974894654657);
        BigInteger y1 = new BigInteger(76216354532345);
        BigInteger a1 = x1 * y1;
        stopwatch.Stop();
        Console.WriteLine(a1.ToString("n0") + " (" + stopwatch.Elapsed.TotalMilliseconds.ToString("0.000") + "ms)");

        stopwatch.Restart();
        decimal x2 = 87974894654657M;
        decimal y2 = 76216354532345M;
        decimal a2 = x2 * y2;
        stopwatch.Stop();
        Console.WriteLine(a2.ToString("n0") + " (" + stopwatch.Elapsed.TotalMilliseconds.ToString("0.000") + "ms)");

这里输出:

6.705.125.760.945.040.000.000.000.000(0,002ms)

6.705.125.760.945.040.955.511.380.665(0,044ms)

6.705.125.760.945.040.955.511.380.665(0,030ms)

<强>更新

通过1000万次的迭代,可以更好地看到数据类型之间的性能:

双倍:6.705.125.760.945.040.000.000.000.000(24,558ms)

BigInteger:6.705.125.760.945.040.955.511.380.665(1623,420ms)

十进制:6.705.125.760.945.040.955.511.380.665(478,333ms)