0
int n = Convert.ToInt32(Console.ReadLine());
int factorial = 1;
    
for (int i = 1; i <= n; i++)
{
    factorial *= i;    
}
Console.WriteLine(factorial);

This code runs in Console Application, but when a number is above 34 the application returns 0.

Why is 0 returned and what can be done to compute factorial of large numbers?

Palle Due
  • 5,929
  • 4
  • 17
  • 32

3 Answers3

6

You're going out of range of what the variable can store. That's effectively a factorial, which grows faster than the exponential. Try using ulong (max value 2^64 = 18,446,744,073,709,551,615) instead of int (max value 2^31 = 2,147,483,647) - ulong p = 1 - that should get you a bit further.

If you need to go even further, .NET 4 and up has BigInteger, which can store arbitrarily large numbers.

McGarnagle
  • 101,349
  • 31
  • 229
  • 260
  • @user169654 yeah, as codesparkle noted in the comments, BigInteger is probably the way to go. You have to add a reference to `System.Numerics` in your project. – McGarnagle Nov 04 '12 at 20:01
  • 1
    +1... Also interesting fact about factorial that it will start returing 0 due to 2^32 portion of the product. – Alexei Levenkov Nov 04 '12 at 20:49
3

You are getting 0 because of the way integer overflow handled in most programming languages. You can easily see what happens if you output results of each computation in a loop (using HEX representation):

int n = Convert.ToInt32(Console.ReadLine());
int factorial = 1;
for (int i = 1; i <= n; i++)
{
  factorial *= i;
  Console.WriteLine("{0:x}", factorial);
}
Console.WriteLine(factorial);

For n = 34 result look like:

1 2 6 18 78 2d0 13b0 ... 2c000000 80000000 80000000 0

Basically multiplying by 2 shifts numbers left and when you multiplied numberer containing enough twos all significant digits will fall out of integer which is 32 bits wide (i.e. first 6 numbers give you 4 twos : 1, 2, 3, 2*2, 5, 2*3, so result of multipying them is 0x2d0 with 4 zero bits at the end).

Alexei Levenkov
  • 98,904
  • 14
  • 127
  • 179
1

If you are using .net 4.0 and want to calculate factorial of 1000, then try to use BigInteger instead of Int32 or Int64 or even UInt64. Your problem statement "doesn't work" is not quite sufficient for me to give some good subjection. Your code will look something like:

using System;
using System.Numerics;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main()
        {
            int factorial = Convert.ToInt32(Console.ReadLine());

            var result = CalculateFactorial(factorial);

            Console.WriteLine(result);
            Console.ReadLine();
        }

        private static BigInteger CalculateFactorial(int value)
        {
            BigInteger result = new BigInteger(1);
            for (int i = 1; i <= value; i++)
            {
                result *= i;
            }
            return result;
        }
    }
}
Ilya Ivanov
  • 23,148
  • 4
  • 64
  • 90
  • " BigInteger "not definition in Code and Compiler give me error! –  Nov 04 '12 at 20:04
  • I've changed it to full Console Application Snnipet – Ilya Ivanov Nov 04 '12 at 20:06
  • i am beginner .sorry(: complier give error. "numerics" not exist in the spacename –  Nov 04 '12 at 20:13
  • it should be System.Numerics namespace. Check it once again. In example above this namespace is spelled correctly. I've run that code on my machine and it produced correct results – Ilya Ivanov Nov 04 '12 at 20:16