This question already has answers here:
Error: Nonnegative width required in format string at (1)
(2 answers)
2D array declaration on FORTRAN77
(5 answers)
Automatic width integer descriptor for input with Fortran
(2 answers)
Closed last month.
program diziler
implicit none
integer :: N, i
real :: arr(N), sum, mean, stddev, var
! Get the value of N
write(*,'(A)') "Enter the number of elements in the array:"
read(*,'(I)') N
! Get the elements of the array
write(*,'(A)') "Enter the elements of the array:"
do i = 1, N
read(*,'(F)') arr(i)
sum = sum + arr(i)
end do
! Calculate the mean
mean = sum / N
! Calculate the variance
do i = 1, N
var = var + (arr(i) - mean)**2
end do
var = var / N
! Calculate the standard deviation
stddev = sqrt(var)
! Print the results
write(*,'(A,F)') "Mean: ", mean
write(*,'(A,F)') "Standard deviation: ", stddev
end program diziler
it gives error like this
C:\Users\Teknik\Desktop\6.odev.F95(8) : error 270 - Missing width count for 'I' descriptor
C:\Users\Teknik\Desktop\6.odev.F95(13) : error 270 - Missing width count for 'F' descriptor
C:\Users\Teknik\Desktop\6.odev.F95(30) : error 270 - Missing width count for 'F' descriptor
C:\Users\Teknik\Desktop\6.odev.F95(31) : error 270 - Missing width count for 'F' descriptor
C:\Users\Teknik\Desktop\6.odev.F95(3) : error 542 - N appears in the dimension of a variable, yet is not a dummy argument, a variable available through USE or CONTAINS association, a COMMON variable, a PARAMETER, or
Related
I am writing a program to calculate the roots of a polynomial. The user is prompted a polynomial of no greater than fourth order (not a file read). How do I read a polynomial input in Fortran? I thought about using 1D array, each index representing the degree and the number representing the coefficient, but what about the plus and minus signs? I don't want to restrict the user to a polynomial with one mathematical operation.
If you don't care about pretty printing the polynomial without brackets it's not that difficult:
program prompt_read
implicit none
integer, parameter :: wp = kind(1.0d0) ! work precision
!> Polynomial coefficients (maximum degree = 4), only real values allowed
real(wp) :: a(0:4)
!> Polynomial degree
integer :: n
! initialize coefficients to zero
a = 0
write(*,'(A)',advance='no') "Enter polynomial degree (1-4): "
read(*,*) n
! handle erroneous input
if (n > 4 .or. n < 1) then
write(*,'(A)') 'Input error. Try again.'
stop
end if
write(*,'(A)',advance='no') "Enter polynomial coefficients (ascending powers of x): "
read(*,*) a(0:n)
write(*,'(A)') "The polynomial received was " // polystr(a(0:n))
! ... continue with calculation of roots
contains
pure function polystr(coeffs)
real(wp), intent(in) :: coeffs(0:)
character(len=:), allocatable :: polystr
character(32) :: s
integer :: i
write(s,'("(",F0.3,")")') coeffs(0)
polystr = trim(s)
do i = 1, ubound(coeffs,1)
write(s,'("(",F0.3,")")') coeffs(i)
if (i == 1) then
s = trim(s) // '*x'
else if (i > 1) then
s = trim(s) // '*x^' // achar(iachar('0') + i)
end if
polystr = polystr // ' + ' // trim(s)
end do
end function
end program
Example output:
$ gfortran -Wall -o prompt_read prompt_read.f90
$ ./prompt_read
Enter polynomial degree (1-4): 3
Enter polynomial coefficients (ascending powers): 1,-2,3.,-4.2
The polynomial entered is (1.000) + (-2.000)*x + (3.000)*x^2 + (-4.200)*x^3
A few notes/ideas:
use a custom lower bound of 0 to make the array index match the power of the monomial
you can read both space- or comma-delimited input
the polystr function can only handle polynomials up to degree 9
have a look at polyroots-fortran, a collection of existing polynomial root solvers in Fortran
put the body of the program in an "infinite" do-end do loop with a suitable exit condition (for example upon pressing the key q); add a brief help message to explain usage of the program
This question already has answers here:
Fortran: handling integer values of size: ~700000000000
(6 answers)
How do I do big integers in Fortran?
(1 answer)
Closed 8 months ago.
I'm trying to write a Fortran code which checks if a user input number is a prime or not. The code is given below,
program cp
implicit none
integer(kind=8) :: nmb, ind
real*16 :: sqnmb, real_nmb
print*, "Largest value for a is ", huge(nmb)
DO
print *,"Enter the number larger than 0:"
read (*,*) nmb
IF ( nmb <= 0) THEN
print *, "Please enter a number larger than 0."
END IF
IF ( nmb > 0) THEN
EXIT
END IF
END DO
sqnmb = sqrt(real(nmb))
do ind= 2, int(sqnmb), 1
IF (mod(nmb,ind) == 0) THEN
print *, "The number", nmb ,"is not a prime, it is divisible by",ind
STOP
END IF
end do
print *, "The number", nmb ,"is a prime"
end program cp
The program works fine for all numbers below 9223372036854775807(19 digits) which is the largest number that can be defined with the integer(kind=8) type. However, I want to calculate for numbers with 25 digits. How can we define larger integers in Fortran?
This question already has answers here:
Does Fortran preserve the value of internal variables through function and subroutine calls?
(3 answers)
Closed 2 years ago.
I'm recently studying Fortran, and trying to make a program to check the prime number. The function works fine without any loop. It can give 1 when the given number is a prime number and 0 otherwise. However, it doesn't work properly when it is used in do while loop. In the range of 2 ~ 10, it is supposed to give 1 (for 2), 1(for 2), 0(for 4), 1(for 5), 0(for 6), etc. But, it keeps showing only 0. I'm pretty new to programming, so I'm not sure what I'm missing. I know there are many answers related to prime numbers, but I don't see any issue like this.
** Function checking prime numbers **
module prime_function
contains
integer function isPrime(inp_num)
implicit none
integer :: inp_num
integer :: i = 1
integer :: temp1 = 0
do while (i < inp_num)
i = i + 1
if(mod(inp_num, i) == 0) then
exit
end if
end do
if(inp_num == i) then
temp1 = 1
else
temp1 = 0
end if
isPrime = temp1
end function
end module
program fortran_q
use prime_function
implicit none
integer :: ii, a
a = isPrime(10)
print *, "10 is prime number, so the return : ", a
a = isPrime(11)
print *, "11 is prime number, so the return : ", a
ii = 1
do while (ii < 10)
ii = ii + 1
print *, isPrime(ii)
end do
end program
** Results **
10 is prime number, so the return : 0
11 is prime number, so the return : 1
0
0
0
0
0
0
0
0
0
You have a classic issue for people new to Fortran. The initialization of i and temp0 implies the SAVE attribute. When you call isPrime for the first time the values are set to 1 and 0. On the next invocation, the values of i and temp0 are set to whatever their previous values were when isPrime was last executed. The belong program fixes the issue.
module prime_function
implicit none
private
public isprime
contains
function isPrime(inp_num) result(res)
integer res
integer, intent(in) :: inp_num
integer i, temp1
i = 1
temp1 = 0
do while (i < inp_num)
i = i + 1
if (mod(inp_num, i) == 0) exit
end do
res = 0
if (inp_num == i) res = 1
end function
end module
program fortran_q
use prime_function
implicit none
integer :: ii, a
a = isPrime(10)
print *, "10 is prime number, so the return : ", a
a = isPrime(11)
print *, "11 is prime number, so the return : ", a
ii = 1
do while (ii < 10)
ii = ii + 1
print *, isPrime(ii)
end do
end program
I have a set of code in which I declare the size of all my variables. However, I want to change them so some of the variables are allocatable.
This is (what I believe) to be the relevant code of the original.
parameter (m=10**5,nchar=2000,ncols=110)
character (LEN=*), PARAMETER :: FORM = "(A)"
character(LEN=nchar),DIMENSION(m) :: data
* determine the length of the data
nlines = 0
do i = 1,m
read(12,*,end=10)
nlines = nlines+1
end do
nlines = nlines+1
* read in the data
10 REWIND(unit = 12)
do i = 1,nlines
read(12,FORM) data(i)
end do
This is the form I would like.
parameter (m=10**5,nchar=2000,ncols=110)
character (LEN=*), PARAMETER :: FORM = "(A)"
character(LEN=:),DIMENSION(:),allocatable :: data
integer j
character(LEN=100000) :: temp
* determine the length of the data
nlines = 0
j = 0
do while (ios == 0)
read(12,FORM,end=10,iostat=ios) temp
if (LEN(TRIM(temp)) .gt. j) THEN
j = LEN(TRIM(temp))
end if
nlines = nlines+1
end do
nlines = nlines+1
10 REWIND(unit = 12)
ALLOCATE (character(LEN=j) :: data(nlines))
* read in the data
do i = 1,nlines
read(12,FORM) data(i)
end do
Problematically, this causes an integer overflow error. "Fortran runtime error: Integer overflow when calculating the amount of memory to allocate". I find this very perplexing as the 'nlines' and 'j' values I obtain from my test dataset are only 10 and 110 respectively.
I have found that if I don't allocate the character length (i.e. keep it a constant), this works.
I am using gfortran, version 4.8.0.
What is wrong with my code/method?
I'm trying to write a program to find the mean, median, mode of an integer array but am having some complications in finding the mode. The following is the code that I've written so far.
First, the program will prompt user to enter a value for the number of integers that will be entered followed by request to enter that number of integers. The integers are then sorted in ascending order and the mean and median are found.
The problem I am having is when I try to get the mode. I am able to count the number of occurrence of a repetitive value. By finding the value with highest occurrence, we'll be able to find Mode. But I am unsure how to do this. Is there any intrinsic function in Fortran to calculate number of occurrence of input values and the value with highest occurrence?
PROGRAM STATISTICS
!Created by : Rethnaraj Rambabu
IMPLICIT NONE
REAL, DIMENSION(:), ALLOCATABLE:: VAL
REAL TEMP, MEDIAN
REAL EVEN, MEAN, SUM, FMODE
INTEGER N, I,J
WRITE(*,*)' WHAT IS THE VALUE FOR N? '
READ(*,*) N
ALLOCATE(VAL(N))
WRITE(*,*) 'ENTER THE NUMBERS'
OPEN(1,FILE='FILE.TXT')
READ(1,*)(VAL(I),I=1,N)
CLOSE(1)
WRITE(*,*) VAL
!/---FOR SORTING----/!
DO I=1,N-1
DO J=1,N-1
IF(VAL(J) > VAL(J+1)) THEN
TEMP=VAL(J)
VAL(J)=VAL(J+1)
VAL(J+1)=TEMP
END IF
END DO
END DO
WRITE(*,*) VAL
!/-----MEDIAN----/!
IF ((N/2*2) /= N) THEN
MEDIAN=VAL((N+1)/2)
ELSE IF ((N/2*2) == N) THEN
EVEN= (VAL(N/2)+VAL((N+2)/2))
MEDIAN=EVEN/2
END IF
WRITE(*,*)'MEDIAN=', MEDIAN
!/----MEAN----/
SUM=0
DO I=1,N
SUM=SUM+VAL(I)
END DO
MEAN=SUM/N
WRITE(*,*)'MEAN=', MEAN
!/------MODE----/
FMODE=1
DO I=1,N-1
IF (VAL(I) == VAL(I+1)) THEN
FMODE=FMODE+1
END IF
END DO
WRITE(*,*)FMODE
END PROGRAM
The FILE.TXT contains
10 8 1 9 8 9 9 7 5 9 3 5 6
But, how to do that? Or is there any intrinsic function in Fortran to calculate number of occurrence of input values and the value with highest occurrence.
No, there is not. You'll have to calculate the mode by hand.
The following code should work (on a sorted array):
FMODE = VAL(1)
COUNT = 1
CURRENTCOUNT = 1
DO I = 2, N
! We are going through the loop looking for values == VAL(I-1)...
IF (VAL(I) == VAL(I-1)) THEN
! We spotted another VAL(I-1), so increment the count.
CURRENTCOUNT = CURRENTCOUNT + 1
ELSE
! There are no more VAL(I-1)
IF (CURRENTCOUNT > COUNT) THEN
! There were more elements of value VAL(I-1) than of value FMODE
COUNT = CURRENTCOUNT
FMODE = VAL(I-1)
END IF
! Next we are looking for values == VAL(I), so far we have spotted one...
CURRENTCOUNT = 1
END
END DO
IF (CURRENTCOUNT > COUNT) THEN
! This means there are more elements of value VAL(N) than of value FMODE.
FMODE = VAL(N)
END IF
Explanation:
We keep the best-so-far mode in the FMODE variable, and the count of the FMODE in the COUNT variable. As we step through the array we count the number of hits that are equal to what we are looking at now, in the CURRENTCOUNT variable.
If the next item we look at is equal to the previous, we simply increment the CURRENTCOUNT. If it's different, then we need to reset the CURRENTCOUNT, because we will now count the number of duplications of the next element.
Before we reset the CURRENTCOUNT we check if it's bigger than the previous best result, and if it is, we overwrite the previous best result (the FMODE and COUNT variables) with the new best results (whatever is at VAL(I) and CURRENTCOUNT), before we continue.
This reset doesn't happen at the end of the loop, so I inserted another check at the end in case the most frequent element happens to be the final element of the loop. In that case we overwrite FMODE, like we would have done in the loop.
It is a bit lengthy, you could probably get rid of the optional argument, but there is an example provided here. They use the quick sort algorithm as implemented here.
Alternatively, you could use
integer function mode(arr) result(m)
implicit none
integer, dimension(:), intent(in) :: arr
! Local variables
integer, dimension(:), allocatable :: counts
integer :: i, astat
character(len=128) :: error_str
! Initialise array to count occurrences of each value.
allocate(counts(minval(arr):maxval(arr)), stat=astat, errmsg=error_str)
if (astat/=0) then
print'("Allocation of counts array failed.")'
print*, error_str
end if
counts = 0
! Loop over inputted array, counting occurrence of each value.
do i=1,size(arr)
counts(arr(i)) = counts(arr(i)) + 1
end do
! Finally, find the mode
m = minloc(abs(counts - maxval(counts)),1)
end function mode
This doesn't require any sorting.