【问题标题】:What is the equivalent of the Java BigDecimal class in C#?C# 中的 Java BigDecimal 类的等价物是什么?
【发布时间】:2010-05-19 06:44:12
【问题描述】:

BigDecimaljava.math 包中的一个类,它对于处理一定规模的大数字有很多好处。 c# 中是否存在具有此功能的等效类或数据类型。

【问题讨论】:

标签: c# java bigdecimal equivalent


【解决方案1】:

就在最近,我还需要 C# 中的任意精度小数,并在此处发布了这个想法:https://stackoverflow.com/a/4524254/804614

然后我完成了支持所有基本算术和比较运算符的草案,以及与所有典型数值类型和一些指数方法之间的转换,这是我当时需要的。

它当然不全面,但非常实用,几乎可以立即使用。由于这是一晚编码的结果,我不能保证这个东西没有错误或完全准确,但它对我来说非常有用。无论如何,我想在这里发布它,因为我没有找到任何其他方法可以在 C# 中使用任意精度小数,而无需包含大量库(大多数甚至不是 .net,而是 C++ 的包装器),这些库带有各种不必要的东西。

基本思想是使用 .NET 4.0 的 BigInteger 类型和以 10 为底的指数 (Int32) 构建具有任意大尾数的自定义浮点类型。

如果您发现错误/不准确之处、有建议或任何建设性内容,请随时直接编辑我的帖子或发表评论,以便我改进答案。

我不完全确定这是否是放置这个东西的最佳位置,但这是关于这个主题的最热门问题之一,我真的很想分享我的解决方案。 ;)

编辑:我将实现移至 GitHubGist:https://gist.github.com/JcBernack/0b4eef59ca97ee931a2f45542b9ff06d

【讨论】:

  • 出色的工作!这对我的 PI 计算工作非常有用。
  • 这很好。我可能提出的一个建议是不要否定一元 - 运算符中的尾数,而是返回一个带有否定尾数的新 BigDecimal,以保持不变。否则您可能会发现BigDecimal x = 1.01, y = -x 具有x == y == -1.01 的不良影响。
  • @jimbobmcgee 首先我认为你是对的并且已经在编辑答案,但后来我再次意识到BigDecimal 是一个结构。这意味着一元运算符的参数已经是原始的副本,因此不可能意外修改它。
  • @Gigo - 注意到并接受。 LINQPad 中的快速BigDecimal one = new BigDecimal(1, 0); BigDecimal minusOne = -one; (new { one, minusOne }).Dump("negation?"); 确认了这一点。今天学习新东西真好!
  • 我在我们的解决方案中使用了它,我注意到除法花费了将近 500 毫秒,这主要是由于 NumberOfDigits 函数。将其转换为字符串非常耗时。我用这个替换了那个函数的主体:return (int)Math.Ceiling(BigInteger.Log10(value*value.Sign));
【解决方案2】:

C# 只有 BigInteger 构建它(在 .NET 框架 4 中)。

decimal 的精度是否足以满足您的任务?它是一个 128 位的数字,可以保存 ±1.0 × 10−28 到 ±7.9 × 1028 范围内的值。

【讨论】:

【解决方案3】:

有一个名为 BigNum 的 C# 库可以满足您的需求,并且在某些情况下还具有其他功能。

例如,它有一个平方根函数,而 BigDecimal 没有:

PrecisionSpec precision = new PrecisionSpec(1024, PrecisionSpec.BaseType.BIN);
BigFloat bf = new BigFloat(13, precision);
bf.Sqrt();
Console.WriteLine(bf.ToString());

维基百科在http://en.wikipedia.org/wiki/Arbitrary-precision_arithmetic#Libraries 有一个其他此类库的列表

来源:

【讨论】:

  • 404:库不再可用?
  • 链接已失效,archive.org 没有保留源代码 zip 文件。
  • 拜托,有人可以为此重新上传原件吗?
  • @Rasheed 我添加了一个指向包含源代码的 zip 文件的链接。
  • 第一个链接不再失效。 :) 布局与存档版本略有不同,但无论如何似乎是同一时代。
【解决方案4】:

嗯,除了使用支持 BigDecimal 的第三方库(如果存在)之外,没有简单的解决方法。就我而言,最简单的方法是采用十进制实现(例如从单声道)并使用 BigInteger 类型重写它。在内部,在 mono 的实现中,十进制类型由三个整数组成。所以我认为这并不难实现。我不确定效率。但是,您应该首先考虑使用 codeka 提到的标准十进制类型。

【讨论】:

    【解决方案5】:

    开发数学

    GitHub:

    https://github.com/deveel/deveel-math

    作者 GitHub:

    Antonello Provenzano

    支持:

    • 大型综合体
    • 大十进制
    • 大数学
    • 理性
    • ...

    如何安装

    从 NuGet 包管理控制台,选择将安装库的项目并键入以下命令

    PM> Install-Package dmath
    

    【讨论】:

    • 我不会相信这个库。在某些情况下,添加失败并出现错误“10 的幂太大”以及使用 BigDecimal 的另一种情况,其中 0.5 > 1e-20 返回 false
    • 优秀的图书馆
    【解决方案6】:

    在最初发布问题时,这可能不是一个选项,但在 C# 代码中使用 BigDecimal 的一种非常简单的方法是通过 NuGet 安装 IKVM.NET 包:

    PM> Install-Package IKVM
    

    然后像在 Java 中那样做:

    using System;
    using java.math;
    
    namespace BigDecimalDemo
    {
        class Program
        {
            static void Main(string[] args)
            {
                int n = int.Parse(args[0]);
                Console.WriteLine(Factorial(n));
            }
    
            static BigDecimal Factorial(int n)
            {
                return n == 1
                    ? BigDecimal.ONE
                    : Factorial(n - 1).multiply(new BigDecimal(n));
            }
        }
    }
    

    根据您使用 IKVM 的程度,偶尔可能会遇到互操作问题,但根据我的经验,它通常适用于此类简单的事情。

    【讨论】:

    • IKVM 是将 Java 代码引入 C# 项目的绝佳工具,但将整个 Java 类库添加到您的项目中只是为了引入一个相对简单的类似乎有点过头了。
    【解决方案7】:

    您也可以使用我编写的Math.Gmp.Native NuGet 包。它的源代码在GitHub 上可用,文档在here 上可用。它向 .NET 公开了被称为高度优化的任意精度算术库的 GMP 库的所有功能。

    任意精度浮点数由mpf_t 类型表示。这些浮点数的运算都以mpf_ 前缀开头。例如,mpf_addmpf_cmp。每个操作都给出了源代码示例。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-12-07
      • 2010-11-22
      • 1970-01-01
      • 2011-10-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多