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.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:'|||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|||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).|||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.|||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.|||Never mind that won't work.|||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|||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):
 
No comments:
Post a Comment