Results 1 to 9 of 9
  1. #1
    Join Date
    Sep 2002
    Posts
    11

    Unanswered: Factorial Question

    Hi, folks.

    This might be irrelevant to the SQL, but I have a question regarding the factorial function.

    n! = n(n-1)(n-2)(n-3)...(2)(1)

    I would like to find the value of n when I know the value of n!.

    Does anyone know how to do this?

    TIA.

  2. #2
    Join Date
    Oct 2002
    Posts
    369

    Lightbulb Re: Factorial Question

    Hi, folks. This might be irrelevant to the SQL, but I have a question regarding the factorial function.
    n! = n(n-1)(n-2)(n-3)...(2)(1)
    I would like to find the value of n when I know the value of n!.
    Q1 Does anyone know how to do this?
    TIA.
    A1 All you need to do is loop through an iterative calculation (n times) you can implement as a stored procedure, a Sql Server 2k fn, or just run the tsql:

    Declare
    @vn int,
    @vi int,
    @vFactorialResult BigInt

    Select @vn = 4
    If @vn < 21 And @vn > 0
    Begin
    Select @vi = 1, @vFactorialResult = 1
    -- Check term iteration (loop)
    While @vi <= @vn
    Begin
    -- calculate Factorial Result term
    Select @vFactorialResult = @vFactorialResult * @vi
    -- increment loop iteration counter
    Select @vi = @vi + 1
    End
    Select @vn As 'n:', @vFactorialResult As 'FactorialResult:'
    End
    Else If @vn >= 21
    Begin
    Select @vn As 'n is too large:'
    End
    Else
    Begin
    Select @vn As 'Error n is:'
    End

    -- As a Sql Server 2k fn:
    Create Function dbo.fn_Factorial (@pn int)
    Returns BigInt
    AS
    Begin
    Declare
    @vi int,
    @vFactorialResult BigInt

    If @pn > 21 Or @pn < 0 Return -1
    Select @vi = 1, @vFactorialResult = 1
    -- Check term iteration (loop)
    While @vi <= @pn
    Begin
    -- calculate Factorial Result term
    Select @vFactorialResult = @vFactorialResult * @vi
    -- increment loop iteration counter
    Select @vi = @vi + 1
    End
    Return @vFactorialResult
    End

    -- To use fn_Factorial
    Declare
    @vn int,
    @vFactorialResult BigInt
    Select @vn = 6
    Select @vFactorialResult = [master].[dbo].[fn_Factorial](@vn)
    Select @vn As 'n:', @vFactorialResult As 'FactorialResult:'

  3. #3
    Join Date
    Sep 2002
    Posts
    11
    Sorry, DBA.

    I think my message was not clear.

    I don't know the value of n.
    I only have the value of n!

    Is it possible to enter the value of n!, and get the value of n calculated as output?

    TIA

  4. #4
    Join Date
    Oct 2002
    Posts
    369

    Lightbulb

    Originally posted by iamcrom
    Sorry, DBA.

    I think my message was not clear.

    I don't know the value of n.
    I only have the value of n!

    Is it possible to enter the value of n!, and get the value of n calculated as output?

    TIA
    My mistake, it looked like a simple typographical error. For that you could implement some kind of factoring procedure or an estimation procedure.

    For an estimation based proc it would simply start with a initial guess and converge until the result is either exactly matched e.g.(Factorial 7) or it is determined that the number cannot be a factorial product e.g.(6020). It should be relativly straight forward to implement, (you should have less than 21 possibilities to check), but more complex than the factorial. Finding an optimized algorithim could take a while (and some testing).

  5. #5
    Join Date
    Sep 2002
    Posts
    11
    Thank you, DBA.

    The problem is that I will be choosing one number from 1 to 75, depending on the probability given. This is problematic because getting that probability relates to binomial coefficient, which in turn relates to factorial.

    I will have probability as input, and spit the corresponding number (1 - 75).


    My memory is hazy, but I remember seeing a formula to calculate n in high school. Does anyone remember that formula?

    It is driving me crazy.

  6. #6
    Join Date
    Oct 2002
    Posts
    369
    If you may be certain the number is a factorial product, I think you could simply use a proc similar to the factorial (except altered to succesively examine the modulus result)?

    In that case the last 0 modulo result sould be n (which you could check by running fn_Factorial (n)) For example:

    Select 24%2, 24%3, 24%4, 24%5

    The last 0 result is for 4;

    The check 4! = 24

    If the result doesn't check it wouldn't be a factorial product.

  7. #7
    Join Date
    Oct 2002
    Posts
    369

    Thumbs down

    Never mind that won't work.

  8. #8
    Join Date
    Feb 2002
    Posts
    2,232
    The following assumes that the value you submit is a valid factorial number - if this is not a guarantee then just do a > comparison and bail out once the value exceeds the supplied factorial.

    Declare
    @vi int,
    @vFactorialResult float,
    @vControl float

    select @vControl = 'the n! value
    select @vFactorialResult = 1, @vi = 1
    while @vi < 76
    Begin
    -- calculate Factorial Result term
    Select @vFactorialResult = @vFactorialResult * @vi
    if @vControl = @vFactorialResult
    begin
    Select @vi as 'n found', @vFactorialResult as 'result', @vControl as 'control'
    break
    end
    -- increment loop iteration counter
    Select @vi = @vi + 1
    End

  9. #9
    Join Date
    Oct 2002
    Posts
    369

    Lightbulb

    RE:
    For an estimation based proc it would simply start with a initial guess and converge until the result is either exactly matched e.g.(Factorial 7) or it is determined that the number cannot be a factorial product e.g.(6020). It should be relativly straight forward to implement, (you should have less than 21 possibilities to check), but more complex than the factorial. Finding an optimized algorithim could take a while (and some testing).
    The following should do it to the nearest non-overflow est. n! (I used bigint instead of floats, you could always rewrite it):
    Attached Files Attached Files

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •