James
James

Reputation: 105

Values of numbers being lost (changed) when called in subroutine

I have written two .f90 text files prog1.f90:

    PROGRAM prog1

        READ (5,*) A,B,C

        PRINT*, "A = ",A
        PRINT*, "B = ",B
        PRINT*, "C = ",C

    CALL test(A,B,C)


    END PROGRAM prog1

and aux.f90

    SUBROUTINE test(E,F,G)

        real(kind=8) :: E,F,G

        PRINT*,"E = ",E
        PRINT*,"F = ",F
        PRINT*,"G = ",G

    END SUBROUTINE test

Which are compiled using the Makefile:

    FC = gfortran
    FCFLAGS = -g -fbounds-check
    FCFLAGS = -O2
    FCFLAGS += -I/usr/include

    PROGRAMS = prog1 

    all: $(PROGRAMS)

    prog1: aux.o

    %: %.o
        $(FC) $(FCFLAGS) -o $@ $^ $(LDFLAGS)

    %.o: %.f90
        $(FC) $(FCFLAGS) -c $<

    %.o: %.F90
        $(FC) $(FCFLAGS) -c $<

    .PHONY: clean veryclean

    clean:
        rm -f *.o *.mod *.MOD

    veryclean: clean
        rm -f *~ $(PROGRAMS)

I use this makefile to compile prog1 and then run prog1 with the input file input.inp:

    0.0033943878 0.0018085515 0.0011798956

I expect the output of this code to be

    A = 0.339439E-02     
    B = 0.180855E-02     
    C = 0.117990E-02
    E = 0.339439E-02     
    F = 0.180855E-02     
    G = 0.117990E-02

However it is:

    A = 0.339439E-02     
    B = 0.180855E-02     
    C = 0.117990E-02
    E = 0.100765847236215E-21
    F = 0.750936901926887E-24
    G = 0.261410786221168-313

The number are much much smaller in the subroutine and seem to have no logical connection to the original A,B and C and are returned from the subroutine as such.

I take it my error is to do with the type I am storing these numbers as, i.e. they are not read in as real(kind=8) but are being converted into this type causing the error but I am not sure what the type should be in the subroutine or if this is even the cause. I may just be missing something obvious.

Any help would be appreciated and please tell me if I need to clarify anything I have written.

Thank you for your time.

James

Upvotes: 0

Views: 143

Answers (2)

Stefan
Stefan

Reputation: 2518

You made the common error to forget the IMPLICIT NONE statement at the beginning of your program. (At least, it is heavily recommended to avoid this kind of error.)

As a result, all variables starting with I, J, K, L, M or N are of type INTEGER(4) and all other variables of type REAL(4). This means, that your variables A, B and C are of REAL(4). Passing them to the subroutine results in principle in an undetected type mismatch which results in misinterpreted values.

You should always place IMPLICIT NONE at the beginning of your programs and modules to be forced to specify explicit types for your variables!

Upvotes: 2

James
James

Reputation: 105

I think I have fixed this error by correcting prog1.f90:

PROGRAM prog1

    real(kind=8) :: A,B,C

    READ (5,*) A,B,C

    PRINT*, "A = ",A
    PRINT*, "B = ",B
    PRINT*, "C = ",C

    CALL test(A,B,C)


END PROGRAM prog1

Upvotes: 0

Related Questions