# Print a Formatted Array

1. Oct 8, 2015

### Sue Parks

I have a list of factorials from 1 -100. I can print them to the console without a format problem. I used the kind() function for formatting the output. I have tried to put these numbers into an array, but I get an error when I try to print the array
PRINT *, FACTORIALS (F)
1
Warning: Legacy Extension: REAL array index at (1)

Code (Fortran):

PROGRAM CALCULATE_FACTORIAL
IMPLICIT NONE
INTEGER, PARAMETER:: DIGITS = SELECTED_REAL_KIND(2,40)
REAL (KIND=DIGITS) :: F
REAL, allocatable, DIMENSION(:) :: FACTORIALS ! array that will hold the primes
INTEGER:: A, N
REAL :: ELEMENTS, I

ALLOCATE (FACTORIALS(n))

FACTORIALS (1)= 1.0

F = 1.0
N = 1
I =1
ELEMENTS =0
A=0

DO
print *, F
N =N +1
F =F * N
!F = ELEMENTS
IF ( N == 101 ) THEN
EXIT
END IF
PRINT *, FACTORIALS (F)
END DO

DEALLOCATE (FACTORIALS)

END PROGRAM CALCULATE_FACTORIAL

2. Oct 8, 2015

3. Oct 8, 2015

### Staff: Mentor

The problem that is causing the error you see is the print statement near the bottom of your code. The index of an array has to be in integer value. The expression FACTORIALS(F) has an array index that is real.

1. DIGITS is not being used, so should be deleted.
2. ELEMENTS is set to 0, and not used after that. It too should be deleted.
3. A is set to 0 but not used after that. It should be deleted.
4. Your DO loop could be changed to a DO I = 1, 101 loop.
5. The variable F and the assignment statement F = F * N should be removed. Instead of having a separate variable F, just assign values to the appropriate spot in the FACTORIALS array.
6. I don't think you need two separate variables I and N.
Having extra, unused variables in a program is not a good thing, as it makes it more difficult for a reader to understand what's going on.

4. Oct 10, 2015

### Sue Parks

I HAVE CLEANED UP THE PROGRAM. I AM TRYING TO USE THE KIND() FUNCTION TO GET THE VALUES. I HAVE THE EXPONENTIAL VALUES, BUT I AM CURIOUS ABOUT FILLING THESE VALUES INTO AN ARRAY (SEE COMMENTS). THANKS

SAMPLE OUTPUT:
Sues-MacBook-Air:FORTRAN sueparks$gfortran CALCULATE_FACTORIAL.f90 Sues-MacBook-Air:FORTRAN sueparks$ ./a.out
1 1.00000000000000000000000000000000000
2 2.00000000000000000000000000000000000
3 6.00000000000000000000000000000000000
4 24.0000000000000000000000000000000000
5 120.000000000000000000000000000000000
6 720.000000000000000000000000000000000
7 5040.00000000000000000000000000000000
8 40320.0000000000000000000000000000000
9 362880.000000000000000000000000000000
10 3628800.00000000000000000000000000000
11 39916800.0000000000000000000000000000
12 479001600.000000000000000000000000000
13 6227020800.00000000000000000000000000
14 87178291200.0000000000000000000000000
15 1307674368000.00000000000000000000000
16 20922789888000.0000000000000000000000

Code (Fortran):

PROGRAM CALCULATE_FACTORIAL
IMPLICIT NONE
INTEGER, PARAMETER:: M = 100
REAL (KIND = 16) ::  FACT
!INTEGER  ::  F = SELECTED_INT_KIND(2,40)

!INTEGER, DIMENSION (M) :: FACTORIAL  !! ADD FACTORIALS TO ARRAY

INTEGER :: I

FACT = 1
DO i = 1, M
FACT = FACT * I
PRINT *,I , FACT
!WRITE (*,*) FACTORIAL (FACT)
END DO

END PROGRAM CALCULATE_FACTORIAL

Last edited by a moderator: Oct 10, 2015
5. Oct 10, 2015

### Staff: Mentor

6. Oct 10, 2015

### Sue Parks

How to fill an array

7. Oct 10, 2015

### Staff: Mentor

Code (Fortran):
program test
integer, parameter ::  M = 100
integer, dimension(M):: Arr
integer i

do i = 1, M
Arr(i) = 2 * i + 3  ! Or whatever
enddo
end program test
After this program runs, the array Arr will have the values 3, 5, 7, 9, ... , 203 in its 100 cells.

I don't have a fortran compiler any more, so I don't 100% guarantee the above code. It's pretty simple, so it should run as advertised.

8. Oct 10, 2015

### Sue Parks

I have tried this. It is obvious that I get and array!!! BUT the output is not correct.
Sues-MacBook-Air:FORTRAN sueparks$gfortran CALCULATE_FACTORIAL.f90 Sues-MacBook-Air:FORTRAN sueparks$ ./a.out

0.00000000 0.00000000 0.00000000 0.00000000 0.00000000

Code (Fortran):

Real, DIMENSION (M) :: FACTORIAL  !! ADD FACTORIALS TO ARRAY

Fact = 1
DO i = 1, M
FACTORIAL = FACT * I

PRINT *, factorial

END DO

Last edited by a moderator: Oct 10, 2015
9. Oct 10, 2015

### Staff: Mentor

factorial (AKA FACTORIAL in your code) is an array. To access it, include an index, as in factorial(i).

The code should look more like this:
Code (Fortran):

Fact = 1
DO i = 1, M
Fact = Fact * i
Factorial(i) = Fact
END DO

! Now you can display the factorials
DO I = 1, M
Print *, Factorial(I)
END DO

Using the unformatted print statement won't give you the nice output that a formatted WRITE statement will, but we can save that for another time. If you're curious, do a web search for "fortran write".

BTW, I applaud your attempts to use code tags, but they should look like this
[code=fortran] -- no spaces inside the brackets
[/code] -- use forward slash and no spaces

10. Oct 11, 2015

### Sue Parks

I used the kind () function to help. I AM using the WRITE command to write to a file. When I used the PRINT command, I was able to print to 100.
33 8.68331788E+36
34 2.95232803E+38
35 Infinity
36 Infinity
37 Infinity

Code (Fortran):

IMPLICIT NONE
INTEGER, PARAMETER:: M = 100
REAL (KIND = 16) ::  FACT
Real, DIMENSION (M) :: FACTORIAL  !! ADD FACTORIALS TO ARRAY
INTEGER  :: I

OPEN (11,  FILE = "MY_FACTORIALS.out", ACTION = "WRITE")
Fact = 1
DO i = 1, M
FACT = FACT * I
FACTORIAL(I) = FACT
END DO

DO I = 1, M
!PRINT *, FACTORIAL (I)
WRITE (11,*) I, FACTORIAL (I)  !  PRINT ARRAY
END DO
CLOSE(11)

11. Oct 11, 2015

### Staff: Mentor

The fact that this code blew up at 35 has nothing to do with differences between print and write. The reason your values are overflowing for 35 and larger is that you have a mismatch between the variable Fact and your array Factorial. The Fact variable is declared as REAL (KIND=16), while the Factorial array is declared merely as REAL.

Since you're using gfortran, KIND=16 is probably allocating 8 bytes for Fact, not 16 bytes as the KIND value might suggest. See http://people.sc.fsu.edu/~jburkardt/f_src/real_precision/real_precision.html, right under "Examples and Tests". Each element of your array is probably a single-precision real of four bytes, which can hold a maximum value of about $10^{38}$. 8-byte reals can hold much larger values, but when you try to stuff an 8-byte quantity into a space in the array that can hold only 4 bytes, it won't fit.

More info on the gfortran KIND type parameters: https://gcc.gnu.org/onlinedocs/gcc-5.1.0/gfortran/KIND-Type-Parameters.html#KIND-Type-Parameters. Depending on the particular compiler you have, REALs are probably limited to 4 or 8 bytes, and your KIND=16 is likely not helping much. If it were my program, I would make Fact and Factorial DOUBLE PRECISION, which would make them both 8-byte reals.

BTW, your thread title is misleading: "Print a Formatted Array". There is no such thing as a "formatted array." You can print an array using formatted printing, which is where WRITE with a FORMAT statement comes in.

12. Oct 11, 2015

### Sue Parks

I did change FACT and FACTORIAL to DOUBLE PRECISION and that did help. Thank YOU!!!