Reputation: 10351
System.Numerics.BigInteger
lets you multiply large integers together, but is there anything of the same type for floating point numbers? If not, is there a free library I can use?
//this but with floats
System.Numerics.BigInteger maxint = new BigInteger(int.MaxValue);
System.Numerics.BigInteger big = maxint * maxint * maxint;
System.Console.WriteLine(big);
Upvotes: 16
Views: 14639
Reputation: 8867
A decade late, but you can try the BigFloat library, which I’ve been developing the last few years. It is released under the MIT license and is flexible and fast.
Article: A BigFloat Library in C#
GitHub: SunsetQuest/BigFloat
Example Usage:
using BigFloatLibrary;
class Program
{
static void Main()
{
BigFloat a = new BigFloat("1.234567890123456789");
BigFloat b = new BigFloat("987654321.000000000987654321");
BigFloat sum = a + b;
BigFloat product = a * b;
Console.WriteLine($"Sum: {sum}");
Console.WriteLine($"Product: {product}");
}
}
Hope this helps anyone else for a looking a high-precision BigFloat C#. Feel free to share any feedback on GitHub.
Upvotes: 1
Reputation: 117175
It should be considered what the implications would be if there were a BigFloat
type.
BigFloat x = 1.0;
BigFloat y = 3.0;
BigFloat z = x / y;
The answer would be 0.333333333333333333333333333333333333333333333333333333
recurring. Forever. Infinite. Out of Memory Error.
It is easy to construct an infinite BigFloat
.
However, if you are happy to stick to rational numbers, those express by the dividing one integer with another than you can use BigInteger
to build a BigRational
type that can provide arbitrary precision for representing any real number.
BigRational x = 1;
BigRational y = 3;
BigRational z = x / y;
This works and gives us this type:
You can just NuGet BigRational
and you'll find many implementations, including once from Microsoft.
Upvotes: 1
Reputation: 30735
Perhaps you're looking for BigRational? Microsoft released it under their BCL project on CodePlex. Not actually sure how or if it will fit your needs.
It keeps it as a rational number. You can get the a string with the decimal value either by casting or some multiplication.
var r = new BigRational(5000, 3768);
Console.WriteLine((decimal)r);
Console.WriteLine((double)r);
Or with a simple(ish) extension method like this:
public static class BigRationalExtensions
{
public static string ToDecimalString(this BigRational r, int precision)
{
var fraction = r.GetFractionPart();
// Case where the rational number is a whole number
if(fraction.Numerator == 0 && fraction.Denominator == 1)
{
return r.GetWholePart() + ".0";
}
var adjustedNumerator = (fraction.Numerator
* BigInteger.Pow(10, precision));
var decimalPlaces = adjustedNumerator / fraction.Denominator;
// Case where precision wasn't large enough.
if(decimalPlaces == 0)
{
return "0.0";
}
// Give it the capacity for around what we should need for
// the whole part and total precision
// (this is kinda sloppy, but does the trick)
var sb = new StringBuilder(precision + r.ToString().Length);
bool noMoreTrailingZeros = false;
for (int i = precision; i > 0; i--)
{
if(!noMoreTrailingZeros)
{
if ((decimalPlaces%10) == 0)
{
decimalPlaces = decimalPlaces/10;
continue;
}
noMoreTrailingZeros = true;
}
// Add the right most decimal to the string
sb.Insert(0, decimalPlaces%10);
decimalPlaces = decimalPlaces/10;
}
// Insert the whole part and decimal
sb.Insert(0, ".");
sb.Insert(0, r.GetWholePart());
return sb.ToString();
}
}
If it's out of the precision range of a decimal or double, they will be cast to their respective types with a value of 0.0. Also, casting to decimal, when the result is outside of its range, will cause an OverflowException
to be thrown.
The extension method I wrote (which may not be the best way to calculate a fraction's decimal representation) will accurately convert it to a string, with unlimited precision. However, if the number is smaller than the precision requested, it will return 0.0, just like decimal or double would.
Upvotes: 18