【发布时间】:2010-05-19 06:44:12
【问题描述】:
BigDecimal 是java.math 包中的一个类,它对于处理一定规模的大数字有很多好处。 c# 中是否存在具有此功能的等效类或数据类型。
【问题讨论】:
标签: c# java bigdecimal equivalent
BigDecimal 是java.math 包中的一个类,它对于处理一定规模的大数字有很多好处。 c# 中是否存在具有此功能的等效类或数据类型。
【问题讨论】:
标签: c# java bigdecimal equivalent
就在最近,我还需要 C# 中的任意精度小数,并在此处发布了这个想法:https://stackoverflow.com/a/4524254/804614
然后我完成了支持所有基本算术和比较运算符的草案,以及与所有典型数值类型和一些指数方法之间的转换,这是我当时需要的。
它当然不全面,但非常实用,几乎可以立即使用。由于这是一晚编码的结果,我不能保证这个东西没有错误或完全准确,但它对我来说非常有用。无论如何,我想在这里发布它,因为我没有找到任何其他方法可以在 C# 中使用任意精度小数,而无需包含大量库(大多数甚至不是 .net,而是 C++ 的包装器),这些库带有各种不必要的东西。
基本思想是使用 .NET 4.0 的 BigInteger 类型和以 10 为底的指数 (Int32) 构建具有任意大尾数的自定义浮点类型。
如果您发现错误/不准确之处、有建议或任何建设性内容,请随时直接编辑我的帖子或发表评论,以便我改进答案。
我不完全确定这是否是放置这个东西的最佳位置,但这是关于这个主题的最热门问题之一,我真的很想分享我的解决方案。 ;)
编辑:我将实现移至 GitHubGist:https://gist.github.com/JcBernack/0b4eef59ca97ee931a2f45542b9ff06d
【讨论】:
- 运算符中的尾数,而是返回一个带有否定尾数的新 BigDecimal,以保持不变。否则您可能会发现BigDecimal x = 1.01, y = -x 具有x == y == -1.01 的不良影响。
BigDecimal 是一个结构。这意味着一元运算符的参数已经是原始的副本,因此不可能意外修改它。
BigDecimal one = new BigDecimal(1, 0); BigDecimal minusOne = -one; (new { one, minusOne }).Dump("negation?"); 确认了这一点。今天学习新东西真好!
return (int)Math.Ceiling(BigInteger.Log10(value*value.Sign));
C# 只有 BigInteger 构建它(在 .NET 框架 4 中)。
decimal 的精度是否足以满足您的任务?它是一个 128 位的数字,可以保存 ±1.0 × 10−28 到 ±7.9 × 1028 范围内的值。
【讨论】:
有一个名为 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 有一个其他此类库的列表
来源:
【讨论】:
嗯,除了使用支持 BigDecimal 的第三方库(如果存在)之外,没有简单的解决方法。就我而言,最简单的方法是采用十进制实现(例如从单声道)并使用 BigInteger 类型重写它。在内部,在 mono 的实现中,十进制类型由三个整数组成。所以我认为这并不难实现。我不确定效率。但是,您应该首先考虑使用 codeka 提到的标准十进制类型。
【讨论】:
https://github.com/deveel/deveel-math
从 NuGet 包管理控制台,选择将安装库的项目并键入以下命令
PM> Install-Package dmath
【讨论】:
在最初发布问题时,这可能不是一个选项,但在 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 的程度,偶尔可能会遇到互操作问题,但根据我的经验,它通常适用于此类简单的事情。
【讨论】: