replica nfl jerseysreplica nfl jerseyssoccer jerseyreplica nfl jerseys forums.silverfrost.com :: View topic - Factorial
forums.silverfrost.com Forum Index forums.silverfrost.com
Welcome to the Silverfrost forums
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Factorial

 
Post new topic   Reply to topic    forums.silverfrost.com Forum Index -> Suggestions
View previous topic :: View next topic  
Author Message
arctica



Joined: 10 Sep 2006
Posts: 118
Location: United Kingdom

PostPosted: Sat Jan 04, 2025 5:52 pm    Post subject: Factorial Reply with quote

Hello

The factorial function crops up quite a lot would it be handy as an intrinsic function in ftn95? Just a thought.

Code:
program factorial_test
    implicit none
    ! Store integers as 64-bit to handle very large numbers
    integer(kind=4) :: n
    integer(kind=4) :: fact_result

    ! Test the function with n = 20
    n = 20
    fact_result = factorial(n)

    ! Output the result
    print *, "Factorial of ", n, " is: ", fact_result

contains

    recursive function factorial(n) result(fact)

        integer(kind=4) :: n
        integer(kind=4) :: fact

        ! Check for negative or zero values
        if (n < 0) then
            print *, "Error: Factorial is not defined for negative numbers."
            fact = -1  ! Error code for negative input
        else if (n == 0) then
            fact = 1  ! Factorial of 0 is 1
        else
            fact = n * factorial(n - 1)  ! Recursive case
        end if

    end function factorial

end program factorial_test



A quick code testing a large value.

Lester
Back to top
View user's profile Send private message
Kenneth_Smith



Joined: 18 May 2012
Posts: 753
Location: Hamilton, Lanarkshire, Scotland.

PostPosted: Sat Jan 04, 2025 9:47 pm    Post subject: Reply with quote

Lester,

Using the 64 bit compiler, you could do this calculation in one line of fortran.

Use an implied do loop within an array constructor, and then apply the product intrinsic to the array.

Code:
program fact
implicit none
integer    :: n
integer(4) :: ifact
integer(4) :: i
real*8     :: dfact     

do n = -1, 20, 1
  ifact = max( 0, product( [(i, i=1, n, 1)] ) )         ! Max required with /Checkmate
  write(*,'(I3,A,I20)') n, '! = ' , ifact
end do
write(*,*)

do n = 20, 170, 10
  dfact = max ( 0.d0, product( [(dble(i), i=1, n, 1)] ) )
  write(*,'(I3,A,EN20.8)') n, '! = ' , dfact
end do

end program fact
Back to top
View user's profile Send private message Visit poster's website
Kenneth_Smith



Joined: 18 May 2012
Posts: 753
Location: Hamilton, Lanarkshire, Scotland.

PostPosted: Sat Jan 04, 2025 11:22 pm    Post subject: Reply with quote

The code I posted earlier is not portable to other compilers, because of a programmer error!

Code below is, which explicitly deals with negative and zero values of n.

For n .ge. 1 the implied do loop / array constructor / product intrinsic remains the same, which is the real point I was trying to demonstrate.


Code:
program fact
implicit none
integer(4) :: n
integer(4) :: ifact
integer :: i
real*8     :: dfact     

do n = -1, 20, 1
  ifact = ifactorial(n)
  write(*,'(I3,A,I20)') n, '! = ' , ifact
end do

write(*,*)

do n = 20, 170, 10
  dfact = dfactorial(n)
  write(*,'(I3,A,EN20.8)') n, '! = ' , dfact
end do

contains


function ifactorial(n)  result(sol)
integer(4), intent(in) :: n
integer(4) :: i
integer(4) :: sol
  sol = 0
  if (n .ge. 1) sol =  product( [(i, i=1, n, 1)] )
  if (n .eq. 0) sol =  1
end function ifactorial


function dfactorial(n)  result(sol)
integer(4), intent(in) :: n
integer :: i
real*8  :: sol
  sol = 0.d0
  if (n .ge. 1) sol =  product( [(dble(i), i=1, n, 1)] )
  if (n .eq. 0) sol =  1.d0
end function dfactorial

end program fact
Back to top
View user's profile Send private message Visit poster's website
PaulLaidler
Site Admin


Joined: 21 Feb 2005
Posts: 8087
Location: Salford, UK

PostPosted: Sun Jan 05, 2025 7:51 am    Post subject: Reply with quote

Lester

Is there a function like this in the Fortran Standard?
Our focus with respect to development has to be on conforming to the lastest standards.
Back to top
View user's profile Send private message AIM Address
arctica



Joined: 10 Sep 2006
Posts: 118
Location: United Kingdom

PostPosted: Sun Jan 05, 2025 1:34 pm    Post subject: Reply with quote

Thanks for the ideas Ken, code works fine.

I am not aware of factorial being an intrinsic in the latest standard.

One thing we do have in ftn95 is the Gamma function. I know this only works on reals, so not sure how it can be flipped to give the same integer output as Ken's code?

In simple terms, Factorial(n) = Gamma(n + 1). In ftn95 the following works up to n=12, but fails for any value that is greater.

Code:
program test_gamma_factorial
implicit none
  real(kind=2) :: n = 12.0d0
  real(kind=2):: fact
  fact = gamma(n+1.0d0)
  print *, "Factorial of ", int(n), " is ", int(fact)
end program test_gamma_factorial


Lester
Back to top
View user's profile Send private message
Kenneth_Smith



Joined: 18 May 2012
Posts: 753
Location: Hamilton, Lanarkshire, Scotland.

PostPosted: Sun Jan 05, 2025 3:08 pm    Post subject: Reply with quote

Lester, These answer both of your questions.

Code:
program q1
implicit none
  integer :: n
  real*8 :: fact
  integer :: i
  do i = 1, 25
    n = i
    fact = gamma( min( n, 20 ) + 1.0d0 )
    print *, "Factorial of ", int(n), " is ", int(fact,kind=4)
  end do
end program q1


Code:
program q2
implicit none
  real*8 :: fact
  integer :: i
 
  do i = 1, 175, 1
    fact = gamma( min( i, 170 ) + 1.0d0)
    print *, "Factorial of ", i, " is ", fact
  end do

end program q2
Back to top
View user's profile Send private message Visit poster's website
arctica



Joined: 10 Sep 2006
Posts: 118
Location: United Kingdom

PostPosted: Wed Jan 08, 2025 5:58 pm    Post subject: Reply with quote

Thanks for the update Ken.

In conclusion, we can say it is not required as an intrinsic function. A good discussion and helpful coding ideas.

Lester
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    forums.silverfrost.com Forum Index -> Suggestions All times are GMT + 1 Hour
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group