BigDecimal
is a class in the java.math
package that has a lot of benefits for handling big numbers of a certain scale. Is there an equivalent class or data type in c# with this feature.

- 20,233
- 5
- 52
- 56

- 6,548
- 18
- 63
- 91
-
Possible duplicate of [Is there a BigFloat class in C#?](http://stackoverflow.com/questions/10359372/is-there-a-bigfloat-class-in-c) – Ky - Sep 13 '16 at 15:06
7 Answers
Just recently I also needed an arbitrary precision decimal in C# and came across the idea posted here: https://stackoverflow.com/a/4524254/804614
I then completed the draft to support all basic arithmetic and comparison operators, as well as conversions to and from all typical numerical types and a few exponential methods, which I needed at that time.
It certainly is not comprehensive, but very functional and almost ready-to-use. As this is the result of one night coding, I can not assure that this thing is bug free or entirely exact, but it worked great for me. Anyway, I want to publish it here because I did not find any other way to use arbitrary precision decimals in C# without the need to include massive librarys (mostly not even .net, but wrappers to c++), which come with all kinds of unnecessary stuff.
The basic idea is to build a custom floating-point type with an arbitrary large mantissa using the BigInteger type of .NET 4.0 and a base 10 exponent (Int32).
If you find bugs/inaccuracies, have suggestions or anything constructive, please feel free to directly edit my post or leave a comment so I may improve the answer.
I'm not entirely sure if this is the best spot to place this thing, but this is one of the top questions on SO about this topic and I really want to share my solution. ;)
EDIT: I moved the implementation to GitHubGist: https://gist.github.com/JcBernack/0b4eef59ca97ee931a2f45542b9ff06d

- 3,188
- 3
- 29
- 40
-
-
This is nice. One suggestion I might make is not to negate the mantissa in your unary `-` operator, instead to return a new `BigDecimal` with the negated mantissa, for immutablilty. Otherwise you might find that `BigDecimal x = 1.01, y = -x` has the undesired effect of `x == y == -1.01`. – jimbobmcgee Nov 27 '14 at 18:47
-
3@jimbobmcgee First I thought you were right and was already editing the answer, but then I realized again that the `BigDecimal` is a struct. That means the argument into the unary operator is already a copy of the original which makes it impossible to accidentally modify it. – Gigo Nov 28 '14 at 17:25
-
@Gigo - noted and accepted. A quick `BigDecimal one = new BigDecimal(1, 0); BigDecimal minusOne = -one; (new { one, minusOne }).Dump("negation?");` in LINQPad confirms it. Good to learn something new, today! – jimbobmcgee Dec 01 '14 at 15:09
-
I think you need to do another `Normalize` whenever you `Truncate`, otherwise `1.000000005` after `Truncate(8)` is `1.0000000` and doesn't correctly equal `1`. – Nigel Touch Aug 21 '15 at 14:31
-
@NigelTouch You are right, thanks for pointing that out. Should be fixed now. – Gigo Oct 18 '15 at 04:30
-
1I am using this in our solution and I noticed that division was taking almost 500ms due primarily to the NumberOfDigits function. Converting it to a string is quite time consuming. I replaced the body of that function with this: `return (int)Math.Ceiling(BigInteger.Log10(value*value.Sign));` – T. Yates Mar 02 '16 at 14:53
-
C# only has BigInteger
built it (in .NET framework 4).
Is decimal
enough precision for your task? It's a 128-bit number that can hold values in the range ±1.0 × 10−28 to ±7.9 × 1028.

- 71,468
- 13
- 145
- 180
-
5
-
@RaheelKhan do you mean this? https://msdn.microsoft.com/de-de/library/microsoft.solverfoundation.common.rational(v=vs.93).aspx – Janus Troelsen Jun 04 '17 at 08:58
There's a C# library called BigNum that does what you're looking for, and in some cases has additional functionality.
For example, it has a square root function, which BigDecimal doesn't have:
PrecisionSpec precision = new PrecisionSpec(1024, PrecisionSpec.BaseType.BIN);
BigFloat bf = new BigFloat(13, precision);
bf.Sqrt();
Console.WriteLine(bf.ToString());
Wikipedia has a list of other such libraries at http://en.wikipedia.org/wiki/Arbitrary-precision_arithmetic#Libraries
Sources:
- The BigNum library was originally hosted at http://www.fractal-landscapes.co.uk/bigint.html, but that site has been down since 2012. (And then came back up at some point).
- You can find an archive of the site at http://web.archive.org/web/20110721173046/http://www.fractal-landscapes.co.uk/bigint.html.
- There's a copy of the source code at http://www.mediafire.com/file/6axoicc6iszp4sg/BigNum.zip/file

- 2,195
- 1
- 25
- 33
-
-
The link is dead, and archive.org doesn't keep the source code zip files. – kristianp Sep 08 '12 at 09:32
-
-
-
1
-
1The first link isn't dead anymore. :) slightly different layout than archived version, but appears to be the same era regardless. – Jesse Chisholm Mar 03 '21 at 04:00
Well, apart from using third-party libraries with support of the BigDecimal (if they exist), there are no easy workarounds. The most easy way, as far as i am concerned is to take a decimal implementation( from mono for example) and to rewrite it using the BigInteger type. Internally, in mono's implementation, decimal type is composed from three integers. So i don't think that would be hard to implement. I am not sure about efficiency though. You should first however consider using standard decimal type as codeka mentioned.

- 4,983
- 4
- 23
- 28
Deveel Math
GitHub:
https://github.com/deveel/deveel-math
Author GitHub:
Support:
- BigComplex
- BigDecimal
- BigMath
- Rational
- ...
How to Install It
From the NuGet Package Management console, select the project where the library will be installed and type the following command
PM> Install-Package dmath

- 31
- 2
-
2I wouldn't trust this library. I had some cases where an addition failed with an error "power of 10 too big" as well as another case using BigDecimal where 0.5 > 1e-20 returns false – Cedric Mamo Sep 30 '16 at 13:00
-
This may not have been an option when the question was originally posted, but one really easy way to use a BigDecimal
in your C# code is to install the IKVM.NET package via NuGet:
PM> Install-Package IKVM
Then do exactly as you would in 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));
}
}
}
Depending on how far you go with IKVM there can be the occasional interop issue to stumble through but in my experience it usually works great for simple stuff like this.

- 51
- 1
- 5
-
4IKVM is great tool for bringing in java code into a C# project, but adding the entire java class libraries to your project just to bring in one relatively simple class seems overkill. – Sprotty Jan 25 '17 at 12:43
You can also use the Math.Gmp.Native NuGet package that I wrote. Its source code is available on GitHub, and documentation is available here. It exposes to .NET all of the functionality of the GMP library which is known as a highly-optimized arbitrary-precision arithmetic library.
Arbitrary-precision floating-point numbers are represented by the mpf_t type. Operations on these floating-point numbers all begin with the mpf_
prefix. For examples, mpf_add or mpf_cmp. Source code examples are given for each operation.

- 2,817
- 1
- 12
- 19