Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. The Lounge
  3. Factorials (C#)

Factorials (C#)

Scheduled Pinned Locked Moved The Lounge
questioncsharphtmlcom
21 Posts 13 Posters 25 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • M Marc Clifton

    This is not a programming question. I was annoyed to find that the Math class doesn't include a Factorial method, so I went off to google and found this page Fast Recursive Factorial function[^] Here's the fellow's code:

    public static long Factorial(long val)
    {
    return val == 1 ? val:val*Factorial(val - 1);
    }

    I gotta wonder, why people call something fast that has an unnecessary recursive call. [grandpa Marc] Back in the days, function calls were expensive. I realize these things can now be optimized by CPU caching and all that, but still... [/grandpa Marc] OK, so why did I even bother to google for this function? Because first off, I wasn't ready to accept that the Math class doesn't have a factorial method. I figured it might be called "ObfuscatedJustForMarc". And, I figured, there's probably something more going on than just an iterative multiplication, which is the obvious answer. Sure enough! Marc

    X Offline
    X Offline
    Xiangyang Liu
    wrote on last edited by
    #3

    Marc Clifton wrote:

    public static long Factorial(long val) { return val == 1 ? val:val*Factorial(val - 1); } why people call something fast that has an unnecessary recursive call

    I think that's the least of its problems. Try the following and call me tomorrow (or next century): long Result = Factorial(-1); :-D

    My .NET Business Application Framework My Home Page My Younger Son & His "PET"

    M M 2 Replies Last reply
    0
    • G Graham Bradshaw

      Marc Clifton wrote:

      unnecessary recursive call

      Becuase it's the canonical example used when teaching recursion in computer science classes. The fact that a simple loop is faster seems to elude most people.

      A Offline
      A Offline
      Adam Maras
      wrote on last edited by
      #4

      But the recursive function is the elegant solution! :laugh:

      1 Reply Last reply
      0
      • M Marc Clifton

        This is not a programming question. I was annoyed to find that the Math class doesn't include a Factorial method, so I went off to google and found this page Fast Recursive Factorial function[^] Here's the fellow's code:

        public static long Factorial(long val)
        {
        return val == 1 ? val:val*Factorial(val - 1);
        }

        I gotta wonder, why people call something fast that has an unnecessary recursive call. [grandpa Marc] Back in the days, function calls were expensive. I realize these things can now be optimized by CPU caching and all that, but still... [/grandpa Marc] OK, so why did I even bother to google for this function? Because first off, I wasn't ready to accept that the Math class doesn't have a factorial method. I figured it might be called "ObfuscatedJustForMarc". And, I figured, there's probably something more going on than just an iterative multiplication, which is the obvious answer. Sure enough! Marc

        N Offline
        N Offline
        Nemanja Trifunovic
        wrote on last edited by
        #5

        Marc Clifton wrote:

        why people call something fast that has an unnecessary recursive call.

        Not only slow, but dangerous as well - give it a big enough number and you will have a stack overflow.

        Programming Blog utf8-cpp

        X 1 Reply Last reply
        0
        • X Xiangyang Liu

          Marc Clifton wrote:

          public static long Factorial(long val) { return val == 1 ? val:val*Factorial(val - 1); } why people call something fast that has an unnecessary recursive call

          I think that's the least of its problems. Try the following and call me tomorrow (or next century): long Result = Factorial(-1); :-D

          My .NET Business Application Framework My Home Page My Younger Son & His "PET"

          M Offline
          M Offline
          Marc Clifton
          wrote on last edited by
          #6

          LOL! I didn't even see that. So much for my "look at the code and find the problem" skills. I think I was so used to thinking in terms of "val>1" that I didn't even notice the ==. Marc

          Thyme In The Country Interacx My Blog

          1 Reply Last reply
          0
          • N Nemanja Trifunovic

            Marc Clifton wrote:

            why people call something fast that has an unnecessary recursive call.

            Not only slow, but dangerous as well - give it a big enough number and you will have a stack overflow.

            Programming Blog utf8-cpp

            X Offline
            X Offline
            Xiangyang Liu
            wrote on last edited by
            #7

            Nemanja Trifunovic wrote:

            give it a big enough number and you will have a stack overflow

            Or small numbers like 0, -1, -2 Since 0! = 1, it is not implemented correctly for 0.

            My .NET Business Application Framework My Home Page My Younger Son & His "PET"

            1 Reply Last reply
            0
            • M Marc Clifton

              This is not a programming question. I was annoyed to find that the Math class doesn't include a Factorial method, so I went off to google and found this page Fast Recursive Factorial function[^] Here's the fellow's code:

              public static long Factorial(long val)
              {
              return val == 1 ? val:val*Factorial(val - 1);
              }

              I gotta wonder, why people call something fast that has an unnecessary recursive call. [grandpa Marc] Back in the days, function calls were expensive. I realize these things can now be optimized by CPU caching and all that, but still... [/grandpa Marc] OK, so why did I even bother to google for this function? Because first off, I wasn't ready to accept that the Math class doesn't have a factorial method. I figured it might be called "ObfuscatedJustForMarc". And, I figured, there's probably something more going on than just an iterative multiplication, which is the obvious answer. Sure enough! Marc

              P Offline
              P Offline
              PIEBALDconsult
              wrote on last edited by
              #8

              Well that shows why the Math class should contain a Factorial method -- "they" should pick the best (or most difficult to implement) and provide it so "we" can simply use it.

              D 1 Reply Last reply
              0
              • P PIEBALDconsult

                Well that shows why the Math class should contain a Factorial method -- "they" should pick the best (or most difficult to implement) and provide it so "we" can simply use it.

                D Offline
                D Offline
                Dan Neely
                wrote on last edited by
                #9

                IF they did our CS professors would wear out their 0 keys grading assignments like this:

                int FactorialHomeWork(int i)
                {
                Return System.Math.Factorial(i);
                }

                Today's lesson is brought to you by the word "niggardly". Remember kids, don't attribute to racism what can be explained by Scandinavian language roots. -- Robert Royall

                P 1 Reply Last reply
                0
                • X Xiangyang Liu

                  Marc Clifton wrote:

                  public static long Factorial(long val) { return val == 1 ? val:val*Factorial(val - 1); } why people call something fast that has an unnecessary recursive call

                  I think that's the least of its problems. Try the following and call me tomorrow (or next century): long Result = Factorial(-1); :-D

                  My .NET Business Application Framework My Home Page My Younger Son & His "PET"

                  M Offline
                  M Offline
                  Mladen Jankovic
                  wrote on last edited by
                  #10

                  ...or when he gets stack overflow, which should be pretty fast matter of seconds I guess.

                  [Genetic Algorithm Library]

                  X 1 Reply Last reply
                  0
                  • M Mladen Jankovic

                    ...or when he gets stack overflow, which should be pretty fast matter of seconds I guess.

                    [Genetic Algorithm Library]

                    X Offline
                    X Offline
                    Xiangyang Liu
                    wrote on last edited by
                    #11

                    Mladen Jankovic wrote:

                    ...or when he gets stack overflow, which should be pretty fast matter of seconds I guess.

                    Don't you know Marc's other name is Chuck Norris? He is using 64,000,000,000 bit long integers, unlike the rest of us. :-D

                    My .NET Business Application Framework My Home Page My Younger Son & His "PET"

                    modified on Thursday, September 18, 2008 3:24 PM

                    W 1 Reply Last reply
                    0
                    • D Dan Neely

                      IF they did our CS professors would wear out their 0 keys grading assignments like this:

                      int FactorialHomeWork(int i)
                      {
                      Return System.Math.Factorial(i);
                      }

                      Today's lesson is brought to you by the word "niggardly". Remember kids, don't attribute to racism what can be explained by Scandinavian language roots. -- Robert Royall

                      P Offline
                      P Offline
                      PIEBALDconsult
                      wrote on last edited by
                      #12

                      Partial credit if the student makes it an Extension Method?

                      1 Reply Last reply
                      0
                      • M Marc Clifton

                        This is not a programming question. I was annoyed to find that the Math class doesn't include a Factorial method, so I went off to google and found this page Fast Recursive Factorial function[^] Here's the fellow's code:

                        public static long Factorial(long val)
                        {
                        return val == 1 ? val:val*Factorial(val - 1);
                        }

                        I gotta wonder, why people call something fast that has an unnecessary recursive call. [grandpa Marc] Back in the days, function calls were expensive. I realize these things can now be optimized by CPU caching and all that, but still... [/grandpa Marc] OK, so why did I even bother to google for this function? Because first off, I wasn't ready to accept that the Math class doesn't have a factorial method. I figured it might be called "ObfuscatedJustForMarc". And, I figured, there's probably something more going on than just an iterative multiplication, which is the obvious answer. Sure enough! Marc

                        R Offline
                        R Offline
                        Robert C Cartaino
                        wrote on last edited by
                        #13

                        Marc Clifton wrote:

                        I was annoyed to find that the Math class doesn't include a Factorial method

                        Too bad C# doesn't support extension methods for static classes. You could have written something like:

                        public static class MyExtensions
                        {
                        public static ulong factorial(this System.Math, int factor) { ... } ; // THIS WONT WORK
                        }

                        and called : ulong factorial = Math.factorial(10); But... nope. I guess you could do this:

                        namespace MarcsCoolStuff
                        {
                        public static class Math
                        {
                        public static ulong factorial(int factor)
                        {
                        ulong[] factorials = { 1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800,
                        39916800, 479001600, 6227020800, 87178291200, 1307674368000,
                        20922789888000, 355687428096000, 6402373705728000,
                        121645100408832000, 2432902008176640000, 14197454024290336768 };

                                return factorials\[factor\];
                            }
                        }
                        

                        }

                        Wrap the array lookup around a try/catch IndexOutOfRange exception if you want bounds checking. And now you can call: ulong factorial = MarcsCoolStuff.Math.factorial(10); ;) Nah, don't do that. It's too obtuse to "fake" a Math class. It's screaming fast though.

                        S 1 Reply Last reply
                        0
                        • R Robert C Cartaino

                          Marc Clifton wrote:

                          I was annoyed to find that the Math class doesn't include a Factorial method

                          Too bad C# doesn't support extension methods for static classes. You could have written something like:

                          public static class MyExtensions
                          {
                          public static ulong factorial(this System.Math, int factor) { ... } ; // THIS WONT WORK
                          }

                          and called : ulong factorial = Math.factorial(10); But... nope. I guess you could do this:

                          namespace MarcsCoolStuff
                          {
                          public static class Math
                          {
                          public static ulong factorial(int factor)
                          {
                          ulong[] factorials = { 1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800,
                          39916800, 479001600, 6227020800, 87178291200, 1307674368000,
                          20922789888000, 355687428096000, 6402373705728000,
                          121645100408832000, 2432902008176640000, 14197454024290336768 };

                                  return factorials\[factor\];
                              }
                          }
                          

                          }

                          Wrap the array lookup around a try/catch IndexOutOfRange exception if you want bounds checking. And now you can call: ulong factorial = MarcsCoolStuff.Math.factorial(10); ;) Nah, don't do that. It's too obtuse to "fake" a Math class. It's screaming fast though.

                          S Offline
                          S Offline
                          Single Step Debugger
                          wrote on last edited by
                          #14

                          Brilliant!

                          The narrow specialist in the broad sense of the word is a complete idiot in the narrow sense of the word. Advertise here – minimum three posts per day are guaranteed.

                          1 Reply Last reply
                          0
                          • M Marc Clifton

                            This is not a programming question. I was annoyed to find that the Math class doesn't include a Factorial method, so I went off to google and found this page Fast Recursive Factorial function[^] Here's the fellow's code:

                            public static long Factorial(long val)
                            {
                            return val == 1 ? val:val*Factorial(val - 1);
                            }

                            I gotta wonder, why people call something fast that has an unnecessary recursive call. [grandpa Marc] Back in the days, function calls were expensive. I realize these things can now be optimized by CPU caching and all that, but still... [/grandpa Marc] OK, so why did I even bother to google for this function? Because first off, I wasn't ready to accept that the Math class doesn't have a factorial method. I figured it might be called "ObfuscatedJustForMarc". And, I figured, there's probably something more going on than just an iterative multiplication, which is the obvious answer. Sure enough! Marc

                            R Offline
                            R Offline
                            Ri Qen Sin
                            wrote on last edited by
                            #15

                            The largest number representable in .NET for UInt64, Decimal, and Double are about 1.84E19, 3.96E28, and 1.80E308 respectively. The factorial of 28 is already 3.05E29, which is bigger than what any number type (except the Double) can represent in .NET. The Double type has its own problems too. Beyond 4.50E15, integers can't be represented accurately anymore since a Double only has a maximum of 52 bits to represent an integer with. You might as well as craft a method to look up the answer in a pre-made dictionary or table of some sort. I don't know what your needs are or if I'm completely wrong, so feel free to correct me.

                            So the creationist says: Everything must have a designer. God designed everything. I say: Why is God the only exception? Why not make the "designs" (like man) exceptions and make God a creation of man?

                            R M 2 Replies Last reply
                            0
                            • X Xiangyang Liu

                              Mladen Jankovic wrote:

                              ...or when he gets stack overflow, which should be pretty fast matter of seconds I guess.

                              Don't you know Marc's other name is Chuck Norris? He is using 64,000,000,000 bit long integers, unlike the rest of us. :-D

                              My .NET Business Application Framework My Home Page My Younger Son & His "PET"

                              modified on Thursday, September 18, 2008 3:24 PM

                              W Offline
                              W Offline
                              WilliamFalconerUK
                              wrote on last edited by
                              #16

                              loving the chuck norris references! :laugh:

                              Billy. MCPD Windows Developer "Duct tape is like the force, it has a light side, a dark side and it holds the universe together!" - Anonymous my holding page..more coming soon!

                              1 Reply Last reply
                              0
                              • R Ri Qen Sin

                                The largest number representable in .NET for UInt64, Decimal, and Double are about 1.84E19, 3.96E28, and 1.80E308 respectively. The factorial of 28 is already 3.05E29, which is bigger than what any number type (except the Double) can represent in .NET. The Double type has its own problems too. Beyond 4.50E15, integers can't be represented accurately anymore since a Double only has a maximum of 52 bits to represent an integer with. You might as well as craft a method to look up the answer in a pre-made dictionary or table of some sort. I don't know what your needs are or if I'm completely wrong, so feel free to correct me.

                                So the creationist says: Everything must have a designer. God designed everything. I say: Why is God the only exception? Why not make the "designs" (like man) exceptions and make God a creation of man?

                                R Offline
                                R Offline
                                Robert C Cartaino
                                wrote on last edited by
                                #17

                                Ri Qen-Sin wrote:

                                You might as well as craft a method to look up the answer in a pre-made dictionary or table of some sort.

                                I just posted this above:

                                    public static ulong factorial(int factor)
                                    {
                                        ulong\[\] factorials = { 1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800, 
                                                                39916800, 479001600, 6227020800, 87178291200, 1307674368000, 
                                                                20922789888000, 355687428096000, 6402373705728000, 
                                                                121645100408832000, 2432902008176640000, 14197454024290336768 };
                                
                                        return factorials\[factor\];
                                    }
                                

                                An unsigned long value will overrun after 21!.

                                R 1 Reply Last reply
                                0
                                • R Ri Qen Sin

                                  The largest number representable in .NET for UInt64, Decimal, and Double are about 1.84E19, 3.96E28, and 1.80E308 respectively. The factorial of 28 is already 3.05E29, which is bigger than what any number type (except the Double) can represent in .NET. The Double type has its own problems too. Beyond 4.50E15, integers can't be represented accurately anymore since a Double only has a maximum of 52 bits to represent an integer with. You might as well as craft a method to look up the answer in a pre-made dictionary or table of some sort. I don't know what your needs are or if I'm completely wrong, so feel free to correct me.

                                  So the creationist says: Everything must have a designer. God designed everything. I say: Why is God the only exception? Why not make the "designs" (like man) exceptions and make God a creation of man?

                                  M Offline
                                  M Offline
                                  Marc Clifton
                                  wrote on last edited by
                                  #18

                                  Ri Qen-Sin wrote:

                                  I don't know what your needs are or if I'm completely wrong, so feel free to correct me.

                                  I need to get the # of combinations for C(58, 8) or even larger numbers like C(64, 12). Since the math is n! / (k! * (n-k)!) It seems I can simplify this to: ((n) * (n-1) * (n-2) * ... * (n-(k+1)) / k! Which becomes a computation that even a long can handle. Marc

                                  Thyme In The Country Interacx My Blog

                                  R 1 Reply Last reply
                                  0
                                  • R Robert C Cartaino

                                    Ri Qen-Sin wrote:

                                    You might as well as craft a method to look up the answer in a pre-made dictionary or table of some sort.

                                    I just posted this above:

                                        public static ulong factorial(int factor)
                                        {
                                            ulong\[\] factorials = { 1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800, 
                                                                    39916800, 479001600, 6227020800, 87178291200, 1307674368000, 
                                                                    20922789888000, 355687428096000, 6402373705728000, 
                                                                    121645100408832000, 2432902008176640000, 14197454024290336768 };
                                    
                                            return factorials\[factor\];
                                        }
                                    

                                    An unsigned long value will overrun after 21!.

                                    R Offline
                                    R Offline
                                    Ri Qen Sin
                                    wrote on last edited by
                                    #19

                                    Using my calculator, it appears that the Decimal type can handle up to 27!, and the Decimal type happens to have 95-bits for the integer part. I suppose a BigInt type would be used beyond 27! if an exact result is needed.

                                    So the creationist says: Everything must have a designer. God designed everything. I say: Why is God the only exception? Why not make the "designs" (like man) exceptions and make God a creation of man?

                                    1 Reply Last reply
                                    0
                                    • M Marc Clifton

                                      Ri Qen-Sin wrote:

                                      I don't know what your needs are or if I'm completely wrong, so feel free to correct me.

                                      I need to get the # of combinations for C(58, 8) or even larger numbers like C(64, 12). Since the math is n! / (k! * (n-k)!) It seems I can simplify this to: ((n) * (n-1) * (n-2) * ... * (n-(k+1)) / k! Which becomes a computation that even a long can handle. Marc

                                      Thyme In The Country Interacx My Blog

                                      R Offline
                                      R Offline
                                      Ri Qen Sin
                                      wrote on last edited by
                                      #20

                                      Ah, nice. I played around with it, and it seems that n_C_r will work as long as n is less than 68.

                                      So the creationist says: Everything must have a designer. God designed everything. I say: Why is God the only exception? Why not make the "designs" (like man) exceptions and make God a creation of man?

                                      1 Reply Last reply
                                      0
                                      • M Marc Clifton

                                        This is not a programming question. I was annoyed to find that the Math class doesn't include a Factorial method, so I went off to google and found this page Fast Recursive Factorial function[^] Here's the fellow's code:

                                        public static long Factorial(long val)
                                        {
                                        return val == 1 ? val:val*Factorial(val - 1);
                                        }

                                        I gotta wonder, why people call something fast that has an unnecessary recursive call. [grandpa Marc] Back in the days, function calls were expensive. I realize these things can now be optimized by CPU caching and all that, but still... [/grandpa Marc] OK, so why did I even bother to google for this function? Because first off, I wasn't ready to accept that the Math class doesn't have a factorial method. I figured it might be called "ObfuscatedJustForMarc". And, I figured, there's probably something more going on than just an iterative multiplication, which is the obvious answer. Sure enough! Marc

                                        S Offline
                                        S Offline
                                        Stuart Dootson
                                        wrote on last edited by
                                        #21

                                        Marc Clifton wrote:

                                        I gotta wonder, why people call something fast that has an unnecessary recursive call.

                                        Of course, if you write your code in a tail-recursive form, using a language/compiler combo that does tail-call optimisations, it will be as fast as the imperative form. Too bad your fellow's done none of that :-)

                                        1 Reply Last reply
                                        0
                                        Reply
                                        • Reply as topic
                                        Log in to reply
                                        • Oldest to Newest
                                        • Newest to Oldest
                                        • Most Votes


                                        • Login

                                        • Don't have an account? Register

                                        • Login or register to search.
                                        • First post
                                          Last post
                                        0
                                        • Categories
                                        • Recent
                                        • Tags
                                        • Popular
                                        • World
                                        • Users
                                        • Groups