How can I print a formatted array of factorials from 1-100 without errors?

  • Thread starter Thread starter Sue Parks
  • Start date Start date
  • Tags Tags
    Array
Click For Summary

Discussion Overview

The discussion revolves around printing a formatted array of factorials from 1 to 100 in Fortran. Participants explore issues related to array indexing, variable usage, and formatting output, while sharing code snippets and suggestions for improvement.

Discussion Character

  • Technical explanation
  • Debate/contested
  • Homework-related

Main Points Raised

  • One participant describes their attempt to print factorials using an array but encounters an error related to using a real number as an array index.
  • Another participant suggests converting the real value to an integer for proper indexing into the array.
  • Several participants point out unused variables in the code and propose removing them for clarity.
  • There are multiple iterations of code shared, with some participants attempting to clean up the program and others questioning how to fill the array correctly.
  • One participant expresses confusion over the output being incorrect despite having an array, indicating a potential misunderstanding of how to access array elements.
  • Another participant provides a simple example of filling an array but notes they cannot guarantee its correctness due to lack of access to a Fortran compiler.
  • Participants discuss the need for proper indexing when accessing array elements, emphasizing that an index must be included when referencing the array.

Areas of Agreement / Disagreement

Participants generally agree on the need for proper indexing and the removal of unused variables, but there is no consensus on the best approach to fill the factorial array or resolve the output issues.

Contextual Notes

Some participants mention limitations in their code, such as the use of real numbers for array indexing and the presence of unused variables, which may complicate understanding and readability.

Who May Find This Useful

This discussion may be useful for individuals learning Fortran programming, particularly those interested in array manipulation and factorial calculations.

Sue Parks
Messages
38
Reaction score
0
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)

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 DODEALLOCATE (FACTORIALS)END PROGRAM CALCULATE_FACTORIAL
 
Technology news on Phys.org
Sue Parks said:
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)

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 DODEALLOCATE (FACTORIALS)END PROGRAM CALCULATE_FACTORIAL
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.

Some other comments:
  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.
 
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

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:
Sue Parks said:
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

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
What's your question?
 
  • Like
Likes   Reactions: Sue Parks
How to fill an array
 
Sue Parks said:
How to fill an array

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.
 
  • Like
Likes   Reactions: 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
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:
Sue Parks said:
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
Fortran:
Real, DIMENSION (M) :: FACTORIAL  ! ADD FACTORIALS TO ARRAY
 
 
   
          Fact = 1
          DO i = 1, M
              FACTORIAL = FACT * I
       
              PRINT *, factorial
       
          END DO
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:
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
Fortran:
 -- no spaces inside the brackets
-- use forward slash and no spaces
 
  • Like
Likes   Reactions: Sue Parks
  • #10
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

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
Sue Parks said:
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

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)
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.
 
  • Like
Likes   Reactions: Sue Parks
  • #12
I did change FACT and FACTORIAL to DOUBLE PRECISION and that did help. Thank YOU!
 

Similar threads

  • · Replies 17 ·
Replies
17
Views
4K
  • · Replies 4 ·
Replies
4
Views
3K
  • · Replies 13 ·
Replies
13
Views
3K
  • · Replies 23 ·
Replies
23
Views
2K
  • · Replies 6 ·
Replies
6
Views
3K
  • · Replies 5 ·
Replies
5
Views
4K
  • · Replies 3 ·
Replies
3
Views
2K
  • · Replies 4 ·
Replies
4
Views
3K
  • · Replies 8 ·
Replies
8
Views
4K
  • · Replies 2 ·
Replies
2
Views
8K