Reputation: 21
I'm having problems with accurately running this code, the code compiles correctly but for every value I enter for inputsin, I will always receive 1.0 as an answer.
The taylor series for the exponential will start at one by defintion. It's possible my factorial implementation is incorrect, but any editing of the factorial loop renders what seems to be an infinite loop.
program taylor
implicit none
real :: inputexp, inputsine ! The values of input for the arguments of the taylor series
real :: exptaylor, sinetaylor ! The value of the sine and exponential calculated
real :: expseries, sineseries ! The value found by the taylor series
real, parameter :: accuracy = 1.e-10 ! The value of accuracy
integer :: NN, aa, bb, cc, dd, ee, ff, gg, hh ! Loop indices and factorial things
integer:: nfactexp ! Factorial for the exponential series
integer :: Nexp ! Number of turns
write(*,*) "Write the value of the input of the exponential taylor series"
read(*,*) inputexp
! Calculating the exponential function using taylor series
exptaylor = 1 ! Initializing the exponential function taylor arguemnts
! Loop to calculate the exponential function
aa = 0
do while(abs(exptaylor) > accuracy)
! Computing factorial
nfactexp = 1 ! Accounting for 0!=1
do bb = 1, aa
nfactexp = nfactexp*bb
enddo
! Evaluating the series
aa = aa+1
exptaylor = (inputexp**aa)/nfactexp
expseries = exptaylor + expseries
enddo
Write(*,*) "The number of terms of the series, N", aa
Write(*,*) "The value of the exponential according to the taylor series", expseries
end program
Upvotes: 0
Views: 282
Reputation: 1209
You have several problems.
First of all, you are not initializing expseries
. You should set it before the loop. Right now, the result is completely arbitrary, since the initial value of expseries
is undefined.
Second, your variable nfactexp
is overflowing. 32-bit integers, which you probably are using, only allow numbers up to 2 147 483 647. Also, (inputexp**aa)
can overflow. While you cannot fix overflows for all inputs using a finite amount of bits, you can extend the computable area. By computing each expterm
using the last one, as expterm = expterm / aa * inputexp
, you can get the largest range.
The change above also means that you no longer redundantly compute factorial terms, and reduces the exponentiation to a multiplication, making the code faster, too.
Also, the abs
on the while
-loop condition is unnecessary, since expterm
is always non-negative.
See the code below:
program taylor
implicit none
real :: inputexp, exptaylor, expseries
real, parameter :: accuracy = 1.0e-10
integer :: aa
write(*,*) "Write the value of the input of the exponential taylor series"
read(*,*) inputexp
exptaylor = 1 ! The first term is constant
expseries = 1 ! The first term is already included
aa = 0 ! Term index, i.e. 0 for the constant
do while (exptaylor > accuracy)
aa = aa + 1
! Use the previous value of exptaylor.
! Just scale it with the one more inputexp to get the x**n
! correct, and divide by aa for the factorial.
exptaylor = exptaylor / aa * inputexp
expseries = exptaylor + expseries
enddo
Write(*,*) "The number of terms of the series, N", aa
Write(*,*) "The value of the exponential according to the taylor series", expseries
end program
Upvotes: 2