Variable "cluster" to count factorial in c# - c#

Trying to count factorial of a big number, for example 1000!
static void Main(string[] args)
{
UInt64 fact = 1;
for (UInt64 i = 1000; i > 0; i--)
{
fact = fact * i;
}
Console.WriteLine(fact); //returns 0, due to overflow UInt64, max fact is 56!
Console.ReadKey();
}
So i ask, if there is some way to join more variables to cluster, so i can make really large variable to store "big" number.

You can use a BigInteger. This type can store integers of arbitrary size, until you run out of memory.

In .NET 4
BigInteger will do what you want.
Big integers in C# may be of more interest as well since it is a very similar question (well, more a very similar answer).

Related

BigInteger.Pow(BigInteger, BigInteger)?

I'm trying to calculate a large number, which requires BigInteger.Pow(), but I need the exponent to also be a BigInteger and not int.
i.e.
BigInteger.Pow(BigInteger)
How can I achieve this?
EDIT: I came up with an answer. User dog helped me to achieve this.
public BigInteger Pow(BigInteger value, BigInteger exponent)
{
BigInteger originalValue = value;
while (exponent-- > 1)
value = BigInteger.Multiply(value, originalValue);
return value;
}
Just from the aspect of general maths, this doesn't make sense. That's why it's not implemented.
Think of this example: Your BigInteger number is 2 and you need to potentiate it by 1024. This means that the result is a 1 KB number (2^1024). Now imagine you take int.MaxValue: Then, your number will consume 2 GB of memory already. Using a BigInteger as an exponent would yield a number beyond memory capacity!
If your application requires numbers in this scale, where the number itself is too large for your memory, you probably want a solution that stores the number and the exponent separately, but that's something I can only speculate about since it's not part of your question.
If your your issue is that your exponent variable is a BigInteger, you can just cast it to int:
BigInteger.Pow(bigInteger, (int)exponent); // exponent is BigInteger
Pow(2, int64.MaxValue) requires 1,152,921 terabytes just to hold the number, for a sense of scale. But here's the function anyways, in case you have a really nice computer.
static BigInteger Pow(BigInteger a, BigInteger b) {
BigInteger total = 1;
while (b > int.MaxValue) {
b -= int.MaxValue ;
total = total * BigInteger.Pow(a, int.MaxValue);
}
total = total * BigInteger.Pow(a, (int)b);
return total;
}
As others have pointed out, raising something to a power higher than the capacity of int is bad news. However, assuming you're aware of this and are just being given your exponent in the form of a BigInteger, you can just cast to an int and proceed on your merry way:
BigInteger.Pow(myBigInt, (int)myExponent);
or, even better,
try
{
BigInteger.Pow(myBigInt, (int)myExponent);
}
catch (OverflowException)
{
// Do error handling and stuff.
}
For me the solution was to use the function BigInteger.ModPow(BigInteger value, BigInteger exponent, BigInteger modulus) because I needed to do a mod afterwards anyway.
The function calculates a given BigInteger to the power of another BigInteger and calculates the modulo with a third BitInteger.
Although it will still take a good amount of CPU Power it can be evaluated because the function already knows about the modulo and therefore can save a ton of memory.
Hope this might help some with the same question.
Edit:
Is available since .Net Framework 4.0 and is in .Net Standard 1.1 and upwards.
I came up with:
public BigInteger Pow(BigInteger value, BigInteger exponent)
{
BigInteger originalValue = value;
while (exponent-- > 1)
value = BigInteger.Multiply(value, originalValue);
return value;
}

Dividing two Ulong integers outputs wrong result

I am writing a program for Catalan number. So here is the formula for that:
I decided to use the middle part of the formula, because the other parts are too abstract for my knowledge (maybe I slept too much in math classes).
Actually my program works fine for n = 0;,n = 5;, n = 10; But if I enter n = 15; - here comes the boom - the output is 2 when it should be 9694845.
So here is my child:
using System;
namespace _8_Numbers_of_Catalan
{
class CatalanNumbers
{
static void Main()
{
Console.Write("n: ");
int n = int.Parse(Console.ReadLine());
Console.WriteLine("Catalan({0})", n);
//calculating the Catan number from the formula
// Catan(n) = [(2*n)!]/[(n+1)! * n!]
Console.WriteLine((factorial(2 * n)) / (factorial(n + 1) * factorial(n)));
}//finding the factorial
private static ulong factorial(int n)
{
ulong fact = 1;
for (int i = 1; i <= n; i++)
{
fact *= (ulong)i;
}
return fact;
}
}
}
Thank you in advance for understanding me if there is something obviously wrong. I am new in programming.
That is because you are performing calculation of these using integer variables that can contain at most 64 bits.
Your call to factorial(15 * 2) is 30! which would result in a value of
265,252,859,812,191,058,636,308,480,000,000
Much more than fits in a 64 bit integer variable:
18,446,744,073,709,551,615 (0xFFFFFFFFFFFFFFFF).
The options you have are to use a System.Numerics.BigInteger type (slow) or a double (up to a maximum value of 1.7976931348623157E+308). Which means you will loose some precision, that may or may not be relevant.
Another option you have is to use an algorithm to approximate the value of large factorials using an asymptotic approximation such as the Schönhage–Strassen algorithm used by Mathematica.
You may also want to check out some existing online resources for calculation of big factorials in .NET
As a last but not least option (and I have not thoroughly checked) it seems likely to me that specific algorithms exists that allow you to calculate (or approximate to a sufficient accuracy and precision) a Catalan number.
you should use a System.Numerics.BigInteger for this. (add System.Numerics as reference in your project).
private static BigInteger factorial(int n)
{
BigInteger fact = 1;
for (int i = 1; i <= n; i++)
{
fact *= i;
}
return fact;
}
// output: 9694845

How do I implement BN_num_bytes() (and BN_num_bits() ) in C#?

I'm porting this line from C++ to C#, and I'm not an experienced C++ programmer:
unsigned int nSize = BN_num_bytes(this);
In .NET I'm using System.Numerics.BigInteger
BigInteger num = originalBigNumber;
byte[] numAsBytes = num.ToByteArray();
uint compactBitsRepresentation = 0;
uint size2 = (uint)numAsBytes.Length;
I think there is a fundamental difference in how they operate internally, since the sources' unit tests' results don't match if the BigInt equals:
0
Any negative number
0x00123456
I know literally nothing about BN_num_bytes (edit: the comments just told me that it's a macro for BN_num_bits).
Question
Would you verify these guesses about the code:
I need to port BN_num_bytes which is a macro for ((BN_num_bits(bn)+7)/8) (Thank you #WhozCraig)
I need to port BN_num_bits which is floor(log2(w))+1
Then, if the possibility exists that leading and trailing bytes aren't counted, then what happens on Big/Little endian machines? Does it matter?
Based on these answers on Security.StackExchange, and that my application isn't performance critical, I may use the default implementation in .NET and not use an alternate library that may already implement a comparable workaround.
Edit: so far my implementation looks something like this, but I'm not sure what the "LookupTable" is as mentioned in the comments.
private static int BN_num_bytes(byte[] numAsBytes)
{
int bits = BN_num_bits(numAsBytes);
return (bits + 7) / 8;
}
private static int BN_num_bits(byte[] numAsBytes)
{
var log2 = Math.Log(numAsBytes.Length, 2);
var floor = Math.Floor(log2);
return (uint)floor + 1;
}
Edit 2:
After some more searching, I found that:
BN_num_bits does not return the number of significant bits of a given bignum, but rather the position of the most significant 1 bit, which is not necessarily the same thing
Though I still don't know what the source of it looks like...
The man page (OpenSSL project) of BN_num_bits says that "Basically, except for a zero, it returns floor(log2(w))+1.".
So these are the correct implementations of the BN_num_bytes and BN_num_bits functions for .Net's BigInteger.
public static int BN_num_bytes(BigInteger number) {
if (number == 0) {
return 0;
}
return 1 + (int)Math.Floor(BigInteger.Log(BigInteger.Abs(number), 2)) / 8;
}
public static int BN_num_bits(BigInteger number) {
if (number == 0) {
return 0;
}
return 1 + (int)Math.Floor(BigInteger.Log(BigInteger.Abs(number), 2));
}
You should probably change these into extension methods for convenience.
You should understand that these functions measure the minimum number of bits/bytes that are needed to express a given integer number. Variables declared as int (System.Int32) take 4 bytes of memory, but you only need 1 byte (or 3 bits) to express the integer number 7. This is what BN_num_bytes and BN_num_bits calculate - the minimum required storage size for a concrete number.
You can find the source code of the original implementations of the functions in the official OpenSSL repository.
Combine what WhozCraig in the comments said with this link explaining BN_num_bits:
http://www.openssl.org/docs/crypto/BN_num_bytes.html
And you end up with something like this, which should tell you the significant number of bytes:
public static int NumberOfBytes(BigInteger bigInt)
{
if (bigInt == 0)
{
return 0; //you need to check what BN_num_bits actually does here as not clear from docs, probably returns 0
}
return (int)Math.Ceiling(BigInteger.Log(bigInt + 1, 2) + 7) / 8;
}

Problems with large bool array in C#

I decided to write a prime number generator as an easy excerise. The code is pretty simple:
static void generatePrimes (long min, long max)
{
bool[] prime = new bool[max + 1];
for (long i=2; i<max+1; i++)
prime [i] = true;
for (long i=2; i<max+1; i++) {
if (prime [i]) {
if (i>=min)
Console.WriteLine (i);
for (long j=i*2; j<max+1; j+=i)
prime [j] = false;
}
}
Console.WriteLine ();
}
It works just fine with input like 1..10000. However, around max=1000000000 it starts to work EXTREMELY slow; also, mono takes about 1Gb of memory. To me, it seems kinda strange: shouldn't the bool[1000000000] take 1000000000 bits, not bytes? Maybe I'm making some stupid mistake that I don't see that makes it so uneffective?
The smallest unit of information a computer can address is a byte. Thus a bool is stored as a byte. You will need special code to put 8 bools in one byte. The BitArray class does this for you.
Nope. Contrarily to C++'s vector<bool>, in C# an array of bool is, well, an array of bools.
If you want your values to be packed (8 bits per bool), use a BitArray instead.

1000 digit number in C#

I am working on Project Euler and ran into an issue.
I am unable to use a 1000 digit number and wanted to know if I am doing something wrong or am just going about this solution in the wrong way and if so what would be best approach be?
C#
namespace ToThePowerOf
{
class Program
{
static void Main(string[] args)
{
BigInteger n = 1;
int x = 0;
BigInteger [] number;
number = new BigInteger[149194];
number[x] = 1;
number[x + 1] = 1;
x = 3; ;
BigInteger check = 10000000000000000000000000000
0000000000000000000000000000000
0000000000000000000000000000000
0000000000000000000000000000000
0000000000000000000000000000000
0000000000000000000000000000000
0000000000000000000000000000000
0000000000000000000000000000000
0000000000000000000000000000000
00000000000000000000000;
for (int i = 99; i > 0; i--)
{
n = (n - 1) + (n - 2);
number[x] = n;
x++;
if (n > check)
{
Console.WriteLine(x);
}
}
}
}
}
I'm guessing the 'issue' you ran into (would be helpful to include error message) is that the compiler doesn't like the integer literal with 1000 digits so you can't initialise it with a very large integer literal. As others have noted, breaking the integer literal into multiple lines isn't valid either.
The number[x] = 1; lines work because the compiler can handle the integer literal 1 and because we're assigning it to a BigInteger it uses BigInteger's implicit operator to convert it to a BigInteger.
One simple method to get around your problem with the big integer literal is to use the BigInteger.Parse method to create your 1000 digit number.
BigInteger check = BigInteger.Parse("10000....", CultureInfo.InvariantCulture);
Another method could be to initialise it with a small int, then use maths to get to the number you want, as in Jon Skeet's answer.
There's no literal support for BigInteger in C#. So while using BigInteger isn't incorrect, you'll need to work out a different way of instantiating it - e.g. new BigInteger(10).Pow(1000).
Such a big literal isn't possible. Integer literals can be at most 64 bits.
To get a large biginteger, you can either convert from string, or calculate the number instead of hardcoding it. In your case calculating it with BigInteger.Pow(10, digits) is the cleanest solution.
I'm still unsure on the BigInteger handling in C#, however on the Project Euler question you refer to. You can read the number in letter by letter from a text file and convert to an int. Then do the multiplications and checks. Not elegant but it works!
See http://msdn.microsoft.com/en-us/library/system.io.filestream.aspx for syntax ref.
I'm probably really late on this, but what I did was take every number and make it a separate object within an array. I then took the first 5 numbers of the array and multiplied them together and set them to a variable. If they were greater than the max, I set it to the max. I then went on to the next set for numbers 1-6 and did the same etc. I did get an out of range exception. In which case you use a try and get format until you receive this exception. If you want to see the code, I will edit my response, but to save you time on the array, if you still want to attempt this, I will give you the array.
long[] a;
a = new long[] {
7,3,1,6,7,1,7,6,5,3,1,3,3,0,6,2,4,9,1,9,2,2,5,1,1,9,6,7,4,4,2,6,5,7,4,7,4,2,3,5,5,3,4,9,1,9,4,9,3,4,
9,6,9,8,3,5,2,0,3,1,2,7,7,4,5,0,6,3,2,6,2,3,9,5,7,8,3,1,8,0,1,6,9,8,4,8,0,1,8,6,9,4,7,8,8,5,1,8,4,3,
8,5,8,6,1,5,6,0,7,8,9,1,1,2,9,4,9,4,9,5,4,5,9,5,0,1,7,3,7,9,5,8,3,3,1,9,5,2,8,5,3,2,0,8,8,0,5,5,1,1,
1,2,5,4,0,6,9,8,7,4,7,1,5,8,5,2,3,8,6,3,0,5,0,7,1,5,6,9,3,2,9,0,9,6,3,2,9,5,2,2,7,4,4,3,0,4,3,5,5,7,
6,6,8,9,6,6,4,8,9,5,0,4,4,5,2,4,4,5,2,3,1,6,1,7,3,1,8,5,6,4,0,3,0,9,8,7,1,1,1,2,1,7,2,2,3,8,3,1,1,3,
6,2,2,2,9,8,9,3,4,2,3,3,8,0,3,0,8,1,3,5,3,3,6,2,7,6,6,1,4,2,8,2,8,0,6,4,4,4,4,8,6,6,4,5,2,3,8,7,4,9,
3,0,3,5,8,9,0,7,2,9,6,2,9,0,4,9,1,5,6,0,4,4,0,7,7,2,3,9,0,7,1,3,8,1,0,5,1,5,8,5,9,3,0,7,9,6,0,8,6,6,
7,0,1,7,2,4,2,7,1,2,1,8,8,3,9,9,8,7,9,7,9,0,8,7,9,2,2,7,4,9,2,1,9,0,1,6,9,9,7,2,0,8,8,8,0,9,3,7,7,6,
6,5,7,2,7,3,3,3,0,0,1,0,5,3,3,6,7,8,8,1,2,2,0,2,3,5,4,2,1,8,0,9,7,5,1,2,5,4,5,4,0,5,9,4,7,5,2,2,4,3,
5,2,5,8,4,9,0,7,7,1,1,6,7,0,5,5,6,0,1,3,6,0,4,8,3,9,5,8,6,4,4,6,7,0,6,3,2,4,4,1,5,7,2,2,1,5,5,3,9,7,
5,3,6,9,7,8,1,7,9,7,7,8,4,6,1,7,4,0,6,4,9,5,5,1,4,9,2,9,0,8,6,2,5,6,9,3,2,1,9,7,8,4,6,8,6,2,2,4,8,2,
8,3,9,7,2,2,4,1,3,7,5,6,5,7,0,5,6,0,5,7,4,9,0,2,6,1,4,0,7,9,7,2,9,6,8,6,5,2,4,1,4,5,3,5,1,0,0,4,7,4,
8,2,1,6,6,3,7,0,4,8,4,4,0,3,1,9,9,8,9,0,0,0,8,8,9,5,2,4,3,4,5,0,6,5,8,5,4,1,2,2,7,5,8,8,6,6,6,8,8,1,
1,6,4,2,7,1,7,1,4,7,9,9,2,4,4,4,2,9,2,8,2,3,0,8,6,3,4,6,5,6,7,4,8,1,3,9,1,9,1,2,3,1,6,2,8,2,4,5,8,6,
1,7,8,6,6,4,5,8,3,5,9,1,2,4,5,6,6,5,2,9,4,7,6,5,4,5,6,8,2,8,4,8,9,1,2,8,8,3,1,4,2,6,0,7,6,9,0,0,4,2,
2,4,2,1,9,0,2,2,6,7,1,0,5,5,6,2,6,3,2,1,1,1,1,1,0,9,3,7,0,5,4,4,2,1,7,5,0,6,9,4,1,6,5,8,9,6,0,4,0,8,
0,7,1,9,8,4,0,3,8,5,0,9,6,2,4,5,5,4,4,4,3,6,2,9,8,1,2,3,0,9,8,7,8,7,9,9,2,7,2,4,4,2,8,4,9,0,9,1,8,8,
8,4,5,8,0,1,5,6,1,6,6,0,9,7,9,1,9,1,3,3,8,7,5,4,9,9,2,0,0,5,2,4,0,6,3,6,8,9,9,1,2,5,6,0,7,1,7,6,0,6,
0,5,8,8,6,1,1,6,4,6,7,1,0,9,4,0,5,0,7,7,5,4,1,0,0,2,2,5,6,9,8,3,1,5,5,2,0,0,0,5,5,9,3,5,7,2,9,7,2,5,
7,1,6,3,6,2,6,9,5,6,1,8,8,2,6,7,0,4,2,8,2,5,2,4,8,3,6,0,0,8,2,3,2,5,7,5,3,0,4,2,0,7,5,2,9,6,3,4,5,0
};

Categories

Resources