Related
I want to display the progress of a calculation done with a DO-loop, on the console screen. I can print out the progress variable to the terminal like this:
PROGRAM TextOverWrite_WithLoop
IMPLICIT NONE
INTEGER :: Number, Maximum = 10
DO Number = 1, MAXIMUM
WRITE(*, 100, ADVANCE='NO') REAL(Number)/REAL(Maximum)*100
100 FORMAT(TL10, F10.2)
! Calcultations on Number
END DO
END PROGRAM TextOverWrite_WithLoop
The output of the above code on the console screen is:
10.00 20.00 30.00 40.00 50.00 60.00 70.00 80.00
90.00 100.00
All on the same line, wrapped only by the console window.
The ADVANCE='No' argument and the TL10 (tab left so many spaces) edit descriptor works well to overwrite text on the same line, e.g. the output of the following code:
WRITE(*, 100, ADVANCE='NO') 100, 500
100 FORMAT(I3, 1X, TL4, I3)
Is:
500
Instead of:
100 500
Because of the TL4 edit descriptor.
From these two instances one can conclude that the WRITE statement cannot overwrite what has been written by another WRITE statement or by a previous execution of the same WRITE satement (as in a DO-loop).
Can this be overcome somehow?
I am using the FTN95 compiler on Windows 7 RC1. (The setup program of the G95 compiler bluescreens Windows 7 RC1, even thought it works fine on Vista.)
I know about the question Supressing line breaks in Fortran 95 write statements, but it does not work for me, because the answer to that question means new ouput is added to the previous output on the same line; instead of new output overwriting the previous output.
Thanks in advance.
The following should be portable across systems by use of ACHAR(13) to encode the carriage return.
character*1 creturn
! CODE::
creturn = achar(13) ! generate carriage return
! other code ...
WRITE( * , 101 , ADVANCE='NO' ) creturn , i , npoint
101 FORMAT( a , 'Point number : ',i7,' out of a total of ',i7)
There is no solution to this question within the scope of the Fortran standards. However, if your compiler understand backslash in Fortran strings (GNU Fortran does if you use the option -fbackslash), you can write
write (*,"(A)",advance="no") "foo"
call sleep(1)
write (*,"(A)",advance="no") "\b\b\bbar"
call sleep(1)
write (*,"(A)",advance="no") "\b\b\bgee"
call sleep(1)
write (*,*)
end
This uses the backslash character (\b) to erase previously written characters on that line.
NB: if your compiler does not understand advance="no", you can use related non-standard tricks, such as using the $ specifier in the format string.
The following worked perfectly using g95 fortran:
NF = NF + 1
IF(MOD(NF,5).EQ.0) WRITE(6,42,ADVANCE='NO') NF, ' PDFs'//CHAR(13)
42 FORMAT(I6,A)
gave:
5 PDFs
leaving the cursor at the #1 position on the same line. On the next update,
the 5 turned into a 10. ASCII 13 (decimal) is a carriage return.
OPEN(6,CARRIAGECONTROL ='FORTRAN')
DO I=1,5
WRITE(6,'(1H+" ",I)') I
ENDDO
In Fortran, I'm trying to read a file with data in 8-bit (hexadecimal) bytes, on Linux.
In 'hexedit' the first line looks as it should, for the tiff-file it is.
49 49 2A 00 08 00 20 00 00 00 0B 02 00 00 00 00 II*... .........
I declare a two-byte character variable (character(len=2) :: tifhead(8))
and read like this:
open(1,file=filename,access='stream')
read(1) tifhead,greyvalue
I get the first two (49 49), which print out as II in a formatted write
(format (2Z2), but not the other ones.
How can I get all these hex values out? I should see 49 49 2A 00 08 .......
.
Your read statement will simply read 2 characters for tifhead(1), the next 2 characters for tifhead(2), etc, including spaces. Therefore you end up with tifhead(1)="49", tifhead(2)=" 4", tifhead(3)="9 ", and so on. You think you read the first 2 bytes correctly only because you print the strings "49", " 4", "9 ",... one after the other, so it looks like "49 49 " in the output. The compiler has no way to know there is a single blank space separating strings and 2 spaces every four data.
To read your data properly you must use formatted reading which implies you must also declare your stream as 'formatted' in the open statement. The following example shows how this can be done:
program example
implicit none
character(len=2) :: tifhead(8), greyscale(8)
open(1, file="example.txt", access='stream', form='formatted')
read(1, "(4(a2,tr1),tr1,3(a2,tr1),a2)", advance='no') tifhead
read(1, "(tr2,4(a2,tr1),tr1,3(a2,tr1),a2)", advance='no') greyscale
close(1)
print "(a,7(a2,tr1),a2,a)", " tifhead = (", tifhead, ")"
print "(a,7(a2,tr1),a2,a)", "greyscale = (", greyscale, ")"
end program example
Perhaps some explanation is needed: a2,tr1 means read a string of 2 characters, then advance the reading pointer once (this skips the space between your hexadecimal "numbers" - actually, they are treated as just strings). 4(a2,tr1) means do that 4 times. This reads the first 4 bytes plus one space. Now, there is one more space before the next data to be read so we add tr1 to skip it, and our format is 4(a2,tr1),tr1 so far; then we read 3 more bytes with 3(a2,tr1), then the last byte alone with just a2 (not skipping the space after it). So the format string is (4(a2,tr1),tr1,3(a2,tr1),a2), which will read the first 8 bytes correctly, leaving the reading pointer right after the 8th byte. Note that advance='no' is necessary, otherwise Fortran will assume carriage return and will skip the rest of the data in the same record (line).
Now, to read the next 8 bytes we use the same format, except we add tr2 in the beginning to skip the two blank spaces. I added formatted printing in the program to check if data were read correctly. Running the program gives:
tifhead = (49 49 2A 00 08 00 20 00)
greyscale = (00 00 0B 02 00 00 00 00)
which verifies data were read correctly.
Last but not least, I would recommend to avoid old-fashion Fortran used in your code and the example above. This means use newunit to let the program find the first free unit instead of explicitly giving a unit number, have some way to check if the file you are trying to open actually exists or if you reached end of file, avoid unnamed arguments, use the dimension attribute to declare arrays, etc. None of those is strictly necessary, and it might look like unnecessary verbosity at first. But in the long run being strict (as modern Fortran encourages) will save you a lot of time while debugging larger programs. So the above example could (arguably should) be written as follows.
program example2
implicit none
integer :: unt, status
character(len=2), dimension(8) :: tifhead, greyscale
open(newunit=unt, file="example.txt", access='stream', form='formatted',&
action='read', status='old', iostat=status)
if (status /= 0) then
print "(a)","Error reading file."; stop
end if
! More sophisticated reading is probably needed to check for end of file.
read(unit=unt, fmt="(4(a2,tr1),tr1,3(a2,tr1),a2)", advance='no') tifhead
read(unit=unt, fmt="(tr2,4(a2,tr1),tr1,3(a2,tr1),a2)") greyscale
close(unit=unt)
print "(a,7(a2,tr1),a2,a)", " tifhead = (", tifhead, ")"
print "(a,7(a2,tr1),a2,a)", "greyscale = (", greyscale, ")"
end program example2
I wasn't sure if I had to massively modify my previous answers (since I believe they still serve a purpose), so I decided to just add yet another answer, hopefully the last one. I apologize for the verbosity.
The following Fortran 90 module provides a subroutine named tiff_reader_16bit which reads any TIFF data file and returns its 16-bit content in an array of integers:
module tiff_reader
implicit none
private
public :: tiff_reader_16bit
contains
subroutine tiff_reader_16bit(filename, tifdata, ndata)
character(len=*), intent(in) :: filename
integer, allocatable, intent(out) :: tifdata(:)
integer, intent(out) :: ndata
integer, parameter :: max_integers=10000000
integer :: unt, status, record_length, i, records, lsb, msb
character ch;
integer, dimension(max_integers) :: temp
ndata=0
inquire(iolength=record_length) ch
open(newunit=unt, file=filename, access='direct', form='unformatted',&
action='read', status='old', iostat=status, recl=record_length)
if (status /= 0) then
print "(3a)","Error reading file """,filename,""": File not found."; return
end if
records=1
do i=1,max_integers
read(unit=unt, rec=records, iostat=status) ch; msb=ichar(ch)
if (status /= 0) then; records=records-1; ndata=i-1; exit; end if
read(unit=unt, rec=records+1, iostat=status) ch; lsb=ichar(ch)
if (status /= 0) then; ndata=i; temp(ndata)=msb; exit; end if
temp(i)=lsb+256*msb; records=records+2
end do
close(unit=unt)
if (ndata==0) then
print "(a)","File partially read."; records=records-1; ndata=max_integers
end if
allocate(tifdata(ndata), stat=status); tifdata=temp(:ndata)
print "(2(i0,a),/)",records," records read, ",ndata," 16-bit integers returned."
end subroutine tiff_reader_16bit
end module tiff_reader
The subroutine gets the TIFF file name and returns an array of integers, together with the the total number of integers read. Internally, the subroutine uses a fixed-size array temp to temporarily store the data. To save memory, the subroutine returns an allocatable array tifdata which is part of temp, containing the data that was read only. The maximum number of data read is set in the parameter max_integers to 10 million, but can go up to huge(0) if necessary and if memory allows (in my system that's about 2.14 billion integers); it can go even further if you use "higher" kind of integers. Now, there are other ways to do that, avoiding the use of a temporary fixed-size array, but this usually comes at the cost of additional computation time, and I wouldn't go that way. More sophisticated implementations can also be done, but that would add more complexity to the code, and I don't think it fits here.
Since you need the results in the form of 16-bit data, two consecutive bytes from the file must be read, then you treat them as most significant byte first, less significant byte next. This is why the first byte read in each iteration is multiplied by 256. Note that this is NOT always the case in binary files (but it is in TIFF). Some binary files come with less significant byte first.
The subroutine is lengthier than the previous examples I posted, but that's because I added error checking, which is actually necessary. You should always check if the file exists and if end of file has been reached while reading it. Special care must also be taken for TIFF images with an "orphan" last byte (this is indeed the case for the sample file "FLAG_T24.TIF" which I found here - but not the case for the sample image "MARBLES.TIF" found at the same webpage).
An example driver program using the module above would be:
program tiff_reader_example
use tiff_reader
implicit none
integer :: n
integer, allocatable :: tifdata(:)
call tiff_reader_16bit("FLAG_T24.TIF", tifdata, n);
if (n > 0) then
print "(a,7(z4.4,tr1),z4.4,a)", "First 8 integers read: (", tifdata(:8), ")"
print "(a,7(z4.4,tr1),z4.4,a)", " Last 8 integers read: (", tifdata(n-7:), ")"
deallocate(tifdata)
end if
end program tiff_reader_example
Running the program gives:
46371 records read, 23186 16-bit integers returned.
First 8 integers read: (4949 2A00 0800 0000 0E00 FE00 0400 0100)
Last 8 integers read: (F800 F8F8 00F8 F800 F8F8 00F8 F800 00F8)
which is correct. Note that in this case the number of records (= bytes, since the file is opened as unformatted) is not double the number of integers returned. That's because this particular sample image has that "orphaned" last byte I mentioned earlier. Also note that I used another format to print 16-bit hexadecimals, including leading zeroes if needed.
There are more detailed explanations that can be given but this thread is already quite long. Feel free to ask in the comments if something is not clear.
EDIT: By default intel Fortran treats direct access records as 4-byte words, which doesn't seem quite right to me. This unusual behavior can be fixed with a compiler flag, but to avoid the lack of portability in case someone uses that specific compiler without such a flag, I slightly modified the module tiff_reader to take care of this.
Assuming your data are actually stored in binary format (in fact it seems to be a tiff image data file), my first answer is valid only if you convert data to plain text. If you prefer to read the binary file directly, the simplest way I can think of is to open the file with access='direct', and read data byte-by-byte. Each byte is read as a character, then it is converted to an integer, which I guess is more useful than a string supposed to represent a hexadecimal number.
As an example, the following program will read the header (first 8 bytes) from a tiff data file. The example reads data from a sample tiff image I found here, but it works for any binary file.
program read_tiff_data
implicit none
integer :: unt, status, i
character :: ch
integer, dimension(8) :: tifhead
open(newunit=unt, file="flag_t24.tif", access='direct', form='unformatted',
action='read', status='old', iostat=status, recl=1)
if (status /= 0) then
print "(a)","Error reading file."; stop
end if
do i=1,8
read(unit=unt, rec=i) ch; tifhead(i)=ichar(ch)
end do
close(unit=unt)
print "(a,7(i0,tr1),i0,a)", "tifhead = (", tifhead, ")"
end program read_tiff_data
The program gives this output:
tifhead = (73 73 42 0 8 0 0 0)
which is correct. You can easily expand the program to read more data from the file.
If you still need the hexadecimal representation, just replace i0 with z0 in the print statement so that it reads
print "(a,7(z0,tr1),z0,a)", "tifhead = (", tifhead, ")"
This will print the result in hexadecimals, in this case:
tifhead = (49 49 2A 0 8 0 0 0)
Here is the code that works for me. Most of this is comments. Any remarks you may have on the fortran style are most welcome. Please note that I've been familiar with fortran 77 in the past, and learned a little more modern fortran in the process of writing this piece of code
program putiff
c This program is solely intended to read the data from the .tif files made by the CCD camera
c PIXIS 1024F at beamline 1-BM at the Advanced Photon Source, so that they can be manipulated
c in fortran. It is not a general .tif reader.
c A little bit extra work may make this a reader for baseline .tif files,: some of the
c information below may help with such an implementation.
c
c The PIXIS .tif file is written in hex with the little-endian convention.
c The hex numbers have two 8-bit bytes. They are read with an integer(kind=2) declaration.
c When describing an unsigned integer these cover numbers from 0 to 65535 (or 2**16-1).
c For the PIXIS files the first two bytes are the decimal number 18761. The TIFF6 specification
c gives them as a hexadecimal number (0x4949 for a little-endian convention, 4D4D for the
c big-endian convention. The PIXIS files are little-endian.
c
c The next two bytes should be 42 decimal, and 0x2A.
c
c The next 4 bytes give the byte offset for the first image file directory (IFD) that contains
c all the other information needed to understand how the .tif files are put together.
c This number should be read together as a 4 byte integer (kind=4). These (unsigned) integers
c go from 0 to 2**32-1, or 4294967295: this is the maximum file length for a .tif file.
c For the PIXIS this number is 2097160, or 0x200008: in between are the image date for the
c PIXIS's 1024x1024 pixels, each with a two-byte gray range from 0 to 2**16-1 (or 65535 decimal).
c Therefore the PIXIS image can be read without understanding the IFD.
c
c The line right below the hex representation gives the byte order, for the
c little-endian convention indicated by two first bytes. It's 4949 for little-endian,
c in both the first and in the second byte separately. The byte order is then least importan
c part first; with two bytes together, it is byte by byte. For big-endian it is 4D4D.
c
c One way to confirm all this information is to look at the files
c with a binary editor (linux has xxd) or a binary editor (linux has hexedit).
c For the PIXIS image .tif file, the first 8 bytes in hexedit are indeed:
c 49 49 2A 00 08 00 20 00
c For a little-endian file, the bytes are read from the least important to the
c most important within the two-byte number, like this:
c 49 49 2A 00 08 00 20 00
c (34 12) (34 12) (78 56 34 12)
c Here the byte order is indicated below the numbers. The second two-byte number is
c therefore 2+2*16+0*256+0*4096, or 42. Likewise, the last 4-byte number is 0x00200008.
c
c (When the individual byte are read in binary (with 'xxd -b -l 100') this gives
c for the hexadecimals 49 49 2A 00 08 00 20 00
c binary 01001001 01001001 00101010 00000000 00001000 00000000 00100000 00000000
c in ASCII I I * . . . . . )
c After the PIXIS data comes the so-called IFD (Image File Directory).
c These contain 209 bytes. They mean something, but what I do not know. I printed them
c out one by one at the end of the program. Perhaps they are better read in two-byte units
c (right now they are read as 'integer(kind=1); integer(kind=2) may be better). But, then
c there's an odd number so you have to read one separately.
c I want to know these only because I want to use the same .tif format to
c write the results of rctopo (the max, the COM, the FWHM, and the spread).
c I know what's in the first 8 bytes, and what the data are, so I can just
c copy the ifd at the end and count on getting a good .tif file back.
c It's sort of stupid, but it should work.
use iso_fortran_env
implicit logical (A-Z)
integer :: j,jmin,jmax
integer :: k,kmin,kmax
integer :: ifdlength
data jmin,kmin/1,1,/
parameter(jmax=1024,kmax=1024)
parameter(ifdlength=209)
c 8-byte header that starts the PIXIS data file
integer (kind=2) :: tifh12,tifh34 ! each two (8-bit) bytes
integer (kind=4) :: tifh5678 ! 4 bytes
c open and read the file now that you have the correct file name in the sequence
open(newunit=unt,file='tiff_file,access='stream',iostat=ios)
if (ios /= 0) then ; call problem(ios,'read_in_samples'); end if
read (unt) tifh12,tifh34,tifh5678,greyread,ifd
close (unt)
stop
end
On internet, I found this program that demonstrate Evaluating elliptic integrals of first and second kinds (complete)
implicit none
real*8 e,e1,e2,xk
integer i, n
e=1.d-7
print *,' K K(K) E(K) STEPS '
print *,'------------------------------------------'
xk=0.d0
do i = 1, 20
call CElliptic(e,xk,e1,e2,n)
write(*,50) xk,e1,e2,n
xk = xk + 0.05d0
end do
print *,'1.00 INFINITY 1.0000000 0'
stop
50 format(' ',f4.2,' ',f9.7,' ',f9.7,' ',i2)
end
Complete elliptic integral of the first and second kind. The input parameter is xk, which should be between 0 and 1. Technique uses Gauss' formula for the arithmogeometrical mean. e is a measure of the convergence accuracy. The returned values are e1, the elliptic integral of the first kind, and e2, the elliptic integral of the second kind.
Subroutine CElliptic(e,xk,e1,e2,n)
! Label: et
real*8 e,xk,e1,e2,pi
real*8 A(0:99), B(0:99)
integer j,m,n
pi = 4.d0*datan(1.d0)
A(0)=1.d0+xk ; B(0)=1.d0-xk
n=0
if (xk < 0.d0) return
if (xk > 1.d0) return
if (e <= 0.d0) return
et n = n + 1
! Generate improved values
A(n)=(A(n-1)+B(n-1))/2.d0
B(n)=dsqrt(A(n-1)*B(n-1))
if (dabs(A(n)-B(n)) > e) goto et
e1=pi/2.d0/A(n)
e2=2.d0
m=1
do j = 1, n
e2=e2-m*(A(j)*A(j)-B(j)*B(j))
m=m*2
end do
e2 = e2*e1/2.d0
return
end
I have compiled it but I have received the following errors:
gfortran -Wall -c "gauss.f" (nel direttorio: /home/pierluigi/Scrivania)
gauss.f:53.9:
50 format(' ',f4.2,' ',f9.7,' ',f9.7,' ',i2)
1
Error: Invalid character in name at (1)
gauss.f:83.72:
if (dabs(A(n)-B(n)) > e) goto et
1
Warning: Deleted feature: Assigned GOTO statement at (1)
gauss.f:83.35:
if (dabs(A(n)-B(n)) > e) goto et
1
Error: ASSIGNED GOTO statement at (1) requires an INTEGER variable
gauss.f:48.18:
write(*,50) xk,e1,e2,n
1
Error: FORMAT label 50 at (1) not defined
Compilation failed.
Any suggestions please?
EDIT
I have read all your answers and thanks to you I managed to compile the program. I also have another curiosity and I do not know whether to write another question. In the meantime I modify this question. In my program, xk is increased by 0.05. Now I will that the program to read data from a file containing: the minimum value of xk; the maximum value of xk; the number of intervals. I thought:
open (10,file='data/test')
read (10,*) xkmi, xkma
read (10,*) nk
close (10)
lkmi = dlog(xkmi)
lkma = dlog(xkma)
ldk = (lkma-lkmi)/dfloat(nk-1)
In addition, the program must be modified in such a way that the result is written to another file. How can I change the rest of the program? Thank you very much.
Your source code file extension is f which, I think (check the documentation), tells gfortran that the file contains fixed source form. Until Fortran 90 Fortran was still written as if onto punched cards and the location of various bits and pieces of a line is confined to certain columns. A statement label, such as 50 in the first of the error messages, had to be in columns 1 - 6. Two solutions:
Make sure the label is in (some of) those columns. Or, better
Move to free source form, perhaps by changing the file extension to f90, perhaps by using a compilation option (check your documentation).
The error raised by the goto et phrase is, as your compiler has told you, an example of a deleted feature, in which the goto jumps to a statement whose label is provided at run-time, ie the value of et. Either tell your compiler (check ...) to conform to an old standard, or modernise your source.
Fix those errors and, I suspect, the other error messages will disappear. They are probably raised as a consequence of the compiler not correctly parsing the source after the errors.
Because the file has type ".f" gfortan is interpreting it as fixed-source layout. Trying compiling with the free-form layout by using compiler option -ffree-form and see if that works. This probably explains the error about the "invalid character". That statement not being recognized explains the "format not defined error". The "computed goto" is obsolete but valid Fortran. You can ignore that warning. If you wish, later you can modernize the code. For the remaining error, for the "assigned goto", declare "et" as an integer.
I would just do this
10 n = n + 1
! Generate improved values
A(n)=(A(n-1)+B(n-1))/2.d0
B(n)=dsqrt(A(n-1)*B(n-1))
if (dabs(A(n)-B(n)) > e) goto 10
and possibly compile as free form source as others have shown. The label et seems weird and non-standard, possibly a rare vendor extension.
You could also change the lines above to a do-loop with an exit statement (Fortran 90).
(The program compiled for me after the change).
I tested the subroutine and compared with matlab and it was not the same. It is very similar to the algorithm used in Abramowitz's book. Here is the one I wrote that works well, just for comparing.
subroutine CElliptic(m,K,E)
implicit none
real*8 m,alpha,E,K,A,B,C,A_p,B_p,C_0,pi,suma
integer j,N
N=100
alpha=asin(sqrt(m))
pi = 4.d0*datan(1.d0)
A_p=1.0
B_p=cos(alpha)
C_0=sin(alpha)
suma=0.0
do j=1,N
A=(A_p+B_p)/2.0d0
B=dsqrt(A_p*B_p)
C=(A_p-B_p)/2.0d0
suma=suma+2**(j)*C**2
A_p=A
B_p=B
end do
K=pi/(2*A)
E=(1-1.d0/2.d0*(C_0**2+suma))*K
end Subroutine CElliptic
best regards
Ed.
I'm currently porting an application from Fortran to C and need to output some variables to compare results. I'm very new to Fortran, and although i understand the code and have now ported several thousand lines, I'm a noob at writing Fortran code myself.
This code:
write(6,'(A,I3,A,E12.8,A,E12.8,A,E12.8,A,E12.8,A,E12.8)') 'iHyd:',
& ih,'; dzdr: ',dzdr,'; tauray:', tauRay,'; zRay: ',
& zray,'; ampRay: ',realpart(aray),'+j*',
& imagpart(aray),'; qRay: ',qray,'; width :',w
Compiles fine, but when run, the program exits with:
At line 296 of file calcpr.for (unit = 6, file = 'stdout')
Fortran runtime error: Expected INTEGER for item 15 in formatted transfer, got REAL
(A,I3,A,E12.8,A,E12.8,A,E12.8,A,E12.8,A,E12.8)
^
q0: 1432.3944878270595
nArrayR: 501 nArrayZ: 201
iHyd: 1; dzdr: ************; tauray:************; zRay: ************; ampRay: NaN+j* NaN
; qRay:
Besides being really ugly, it doesn't make much sense to me, as ìh is declared as integer*8 and not as real.
So how can i solve this?
I'm counting 6 character&variable specifications in the format statement, but you're printing 8 of them.
edit:
a nicer use of the format statement would be '(A,I3,7(A,E12.8))'
Fortran "recycles" the format if there are more things to be printed than specified in the format statement. If a write statement gives results you don't understand, to diagonose the problem it may be helpful to remove the things printed one at a time until the error goes away.
It says "item 15", which I would take to be down near the end of your list, not ih at the beginning. It's clear that both "w" and "qray" are being printed as REAL; is either one of them an INTEGER? You may need to change the format specifier then.
I have a small program that read some data from binary file and stores it into normal (unformatted) files. Here is the source:
Program calki2e
IMPLICIT NONE
!
DOUBLE PRECISION VAL
INTEGER P,Q,R,S
INTEGER IREC2C
PARAMETER( IREC2C=15000)
INTEGER AND,RSHIFT,LABEL,IMBABS,NX,IB,NFT77
INTEGER IND
DIMENSION IND(IREC2C)
DOUBLE PRECISION XP
DIMENSION XP(IREC2C)
CHARACTER(LEN=12) :: FN77 = 'input08'
CONTINUE
NFT77=77
!----------------------------------------------------------------------
2 CONTINUE
c
open(unit=NFT77,file=FN77,STATUS='OLD',
+ACCESS='SEQUENTIAL',FORM='UNFORMATTED')
open(unit=13,file='calki2e.txt')
REWIND(77)
4100 continue
READ(77) NX,IND,XP
IMBABS=IABS(NX)
DO 100 IB=1,IMBABS
LABEL=IND(IB)
P= AND(RSHIFT(LABEL, 24),255)
Q= AND(RSHIFT(LABEL, 16),255)
R= AND(RSHIFT(LABEL, 8),255)
S= AND( LABEL ,255)
VAL=XP(ib)
IF(P.EQ. Q) VAL=VAL+VAL
IF(R .EQ. S) VAL=VAL+VAL
IF((P .EQ. R).AND.(Q .EQ. S)) VAL=VAL+VAL
write(13,*)P,Q,R,S,val
100 CONTINUE
IF (NX.GT.0) GOTO 4100
CRB
CLOSE(UNIT=NFT77)
!
END
When I compile it using gfortran I obtain double precision in output file but with g77 I get only single precision. What it wrong and how to change it?
Do you mean the "write (13, *) statement. This is "list directed" output. It is a convenience I/O with few rules -- what you get will depend upon the compiler -- it is best used for debugging and "quick and dirty" programs. To reliably get all the digits of double precision, change to a formatted output statement, specifying the number of digits that you need. (It is probably best to switch to gfortran anyway, as g77 is no longer under development.)
your numbers are double precision but you are printing them in free format. You have to specify an explicit format
If you want to keep your code F77, try something like
write(13,1000) P,Q,R,S,val
1000 format(1X,4I7,1X,1E14.10)
The "1X"s mean one space, "4I7" means four seven-width integers, and 1E14.10 means one fourteen-charater width scientific-notation real number with 10 significant digits. Feel free to mess around with the numbers to get it to look right.
This is a pretty good tutorial on the topic.
I would be tempted to set the format on your write statement to something explicit, rather than use * in write(13,*)P,Q,R,S,val.