Introduction
I wanted to write a simple library for C# that allows to do math calculations at any desired precision level.
Background
During the last few months, I have been playing around with math libraries, and started to implement my own precision math library. I stumbled upon the MAPM library (http://www.tc.umn.edu/~ringx004/mapm-main.html) and decided to create something similar for .NET. This library is the result of my work. Basically. it is a rewrite of the MAPM library for .NET.
My goal is to use this library inside a Mandelbrot fractal renderer I have posted here on CodeProject. Theoretically, this should provide endless zooming into the fractal (at the expense of speed). We will soon see what happens ;-)
Using the Code
The header of the Big Num class looks like this:
public partial class BigNumber
{
sbyte signum=0;
int exponent=0;
byte[] mantissa= {0};
int dataLength=1;
...
}
A big number is represented in the form of S * A * 10 ^ B where:
- S ... is the signum
- A ... is the mantissa
- B ... is the exponent
The mantissa is represented as an array of packed bytes.
Each nibble of a byte represents 2 digits of the number.
The mantissa can have an arbitrary length. It is limited to 1 < |a| < 10
Open the project, compile, and run. The included test program will call the function DoTest()
of the library.
Have a look at the DoTest()
function to see how to work with this library. You will find examples of how to:
- assign values to
BigNumber
s - do basic math operations using the overloaded operators +, -, *, and /
- use math functions like rounding sqrt, pow, log10, log2, and more
- calculate 1000! using this library
- calculate the number PI to a desired amount of digits
public static void DoTest()
{
BigNumber A = 0, B = 0, C = 0;
BigNumber PI= new BigNumber();
A = "12345";
Console.WriteLine("assigned value was: " + A.ToFullString() +
"(" + A.ToString() + ")");
A = 123.45;
Console.WriteLine("assigned value was: " + A.ToFullString() +
"(" + A.ToString() + ")");
A = "10E3";
B = "1E4";
C = 10000;
Console.WriteLine("assigned value was: " + A.ToFullString() +
"(" + A.ToString()+")");
Console.WriteLine("10000 = " + A.ToFullString() + " = " +
B.ToFullString() + " = " + C.ToFullString());
A = 1; B = 2; C = 0;
C = A + B;
Console.WriteLine("the result of " + A.ToFullString() + "+" +
B.ToFullString() + "=" + C.ToFullString());
C = A + 3.2;
C = 3.1 + B;
A = "5.141592"; B = "2.91827";
C = A - B;
Console.WriteLine("the result of " + A.ToFullString() +
"-" + B.ToFullString() + "=" + C.ToFullString());
C = A * B;
Console.WriteLine("the result of " + A.ToFullString() +
"*" + B.ToFullString() + "=" + C.ToFullString());
A = 5.0; B = 3.0;
C = A * B;
Console.WriteLine("the result of " + A.ToFullString() +
"*" + B.ToFullString() + "=" + C.ToFullString());
A = 4; B = 0.5;
C = A.Pow(B);
Console.WriteLine("the result of " + A.ToFullString() +
" pow " + B.ToFullString() + "=" + C.ToFullString());
A = 0.5; B = "5E-1";
C = A.Pow(B,16);
Console.WriteLine("the result of " + A.ToFullString() +
" pow " + B.ToFullString() + "=" + C.ToFullString());
A = "1e3";
C = A.Log10();
Console.WriteLine("the result of " + A.ToFullString() +
" Log10 =" + C.ToFullString());
A = "10E3"; B = "1E4"; C=10000 ;
A = BigNumber.BN_E;
C = A.Log();
Console.WriteLine("the result of " + A.ToString() +
" Log =" + C.ToFullString());
A = 3.0;
C = A.Rez();
Console.WriteLine("the result of " + A.ToString() +
" Rez =" + C.ToFullString());
int NumPlaces = 4;
A = 1.53456;
C = A.Round(NumPlaces);
Console.WriteLine("the result of " + A.ToString() +
" Round(" + NumPlaces + ") =" +
C.ToFullString());
NumPlaces = 2;
C = A.Round(NumPlaces);
Console.WriteLine("the result of " + A.ToString() +
" Round(" + NumPlaces + ") =" +
C.ToFullString());
NumPlaces = 0;
C = A.Round(NumPlaces);
Console.WriteLine("the result of " + A.ToString() +
" Round(" + NumPlaces + ") =" +
C.ToFullString());
NumPlaces = 16;
A = 2.0;
C = A.Sqrt(NumPlaces);
Console.WriteLine("the result of " + A.ToString() +
" Sqrt(" + NumPlaces + ") =" +
C.ToFullString());
A = 1.0; B = 0;
try
{
C = A / B;
}
catch (BigNumberException ex)
{
Console.WriteLine("Exception in operation: " + ex.Message);
}
A = 1.0;
for (int i = 1; i <= 1000; i++)
{
A = A * i;
}
Console.WriteLine("the result of 1000!=" + A.ToFullString());
A = A.Round(numDefaultPlaces);
Console.WriteLine("the result of 1000!=" + A.ToString());
DateTime before = DateTime.Now;
NumPlaces = 5000;
CalculatePiAGM(PI, NumPlaces);
TimeSpan ts = DateTime.Now - before;
Console.WriteLine("time for "+NumPlaces+" digits of PI: " +
ts.TotalMilliseconds + "[ms]");
Console.WriteLine(PI.ToFullString());
Console.WriteLine("Press 'x' key to quit test");
while (true)
{
ConsoleKeyInfo i = Console.ReadKey();
if (i.KeyChar == 'x') break;
}
}
History
- 31.08.2009
- 03.09.2009
- Implemented setting values from binary and hex strings
- Fixed a bug in the add function