2

I would like to use FM package capabilities for the study of a problem in number theory. I installed the package, compiled libraries, and ran the two test suites supplied, all without any problems.

I wrote test.f:

   use fmzm

   TYPE (IM), SAVE :: n

   n = 0
   WRITE(*,*) n

   end

and compiled using

gfortran -c -O3 -Wall test.f
gfortran fmsave.o fm.o fmzm90.o test.o -o test

which returned no error or warning. But got disappointed by discovering the output:

./test
200000

The number 200000 appears to be a memory location for the variable n. I experimented a little, and if I change n to complex type (ZM) it outputs 200000, 199999. Similarly if I declare and initialize two variable instead of one.

If I change TYPE (IM), SAVE :: n to INTEGER n, and compile exactly as above, I get the expected 0 as output.

If I replace the code by

   n = 0
   do
   n=n+1
   if (n < 10) WRITE(*,*) n
   end do

then the output 200000 repeats 9 times and then stops. So it is the WRITE function which only finds the location and not the value. PRINT does the same.

veryreverie
  • 2,871
  • 2
  • 13
  • 26
  • 1
    What is the type `im`? As someone not familiar with FMZM I'd have no reason to expect the behaviour of the program to be identical to one where `n` is declared an integer. – francescalus May 24 '21 at 12:11
  • 1
    Does FMZM support and use user-defined derived type input/output? Or what is it supposed to print? – Vladimir F Героям слава May 24 '21 at 12:23
  • 1
    Please see the example code at https://stackoverflow.com/questions/38801846/how-do-i-do-big-integers-in-fortran You will see that you should first get a string using `IM_format( 'i200', n )` and print this string. – Vladimir F Героям слава May 24 '21 at 12:28
  • Because `IM` is a derived type, it isn't obvious what `=`, `<`, `write` do. `n=0` may or may not set a component of `n` to `0`, and `write(*,*) n` may or may not print a component of `n`. It's entirely likely that if `IM` has a component it is merely a reference to another data structure (which is the arbitrary arithmetic part). Unless the type has user defined output, that component which is printed is indeed a "memory reference". (This is just to say, from the detail you provide it is impossible to answer the question without fine knowledge of the particular package.) – francescalus May 24 '21 at 12:33
  • @Vladimir Thank you, that seems to do the trick! – Tommy R. Jensen May 24 '21 at 14:24

1 Answers1

1

As Vladimir points out, unless you write out a value of a standard type, it seems you have to first convert to a string using a maneuver such as

str = im_format('i100', n)
str = adjustl(str)
str = trim(str)
print*, str

where the middle two lines can be left out.

francescalus
  • 30,576
  • 16
  • 61
  • 96