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 Offline
    M Offline
    Marc Clifton
    wrote on last edited by
    #1

    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

    G X N P R 7 Replies 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

      G Offline
      G Offline
      Graham Bradshaw
      wrote on last edited by
      #2

      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 1 Reply 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
        #3

        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

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

          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
          • 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
                                          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