From: fairfield@slacvx.slac.stanford.edu
Newsgroups: comp.lang.fortran
Subject: Re: Question for C ==> Fortran
Date: 29 Jul 92 21:49:01 GMT
Organization: Stanford Linear Accelerator Center

Sorry to post to the net; the MAIL message I sent bounced...  Also, please
don't flame me for use VAX/VMS extensions, etc., the poster said s/he was
using a VAX ;-)

In article <1992Jul28.075514.28683@debbie.cc.nctu.edu.tw>, linsbin@cc.nctu.edu.tw (Lin shyh bin) writes:
>    Hi, I am unfamiliar to FORTRAN, but I want to write a FORTRAN program as
>
>like the follow C program.
>
>    Could anyone tell me how to transfer it on VAX FORTRAN ?
>
>    #include <stdio.h>
>    #include <math.h>
>
>    #define  MASK 0x1f800000
>
>    union dandi {
>          int     i[2];
>          double  d;
>    } di;
>
>    main()
>    {
>     float  f;
>     double d;
>
>     for (f=0 ; f<1 ; f+=0.000001) {
>         d = (double) f;
>         di.d = sin(d);
>         if ((di.i[1] & MASK) == 0) printf("\n Sine in hex : %x", di.i[1]);
>     }
>    }
>
>
>    Thanks in advance !!

    This is straight-forward in VMS Fortran, since VMS Fortran supports
hexadecimal (as well as octal and binary) constants.  Also, VMS Fortran
supports UNIONs within STRUCTUREs, which should be transparent to a C
programmer.  However, I'll give an example using EQUIVALENCE, first, since 
that is much more standard (the STRUCTURE stuff is part of Fortran 90, but
F90 uses a different syntax than VMS Fortran, so let's not confuse the
issue...)

    The fragment of code above would translate as (note that the exclamation
point is a comment delimitor in VMS Fortran):

        PROGRAM TEST

	IMPLICIT NONE	! Force all variables to be explicitly declared

        INTEGER    MASK
        PARAMETER (MASK='1F800000'X)    ! You can use the PARAMETER statement

        INTEGER             II(2)
        DOUBLE PRECISION    DI
        EQUIVALENCE        (II,DI)

        REAL                F
        DOUBLE PRECISION    D


        DO F=0.0, 0.999999, 0.000001
          D  = DBLE(F)          ! "Cast", rather convert, F to a double.
          DI = SIN(D)           ! Compiler automatically chooses the double-
                                ! precision version of the SIN function.
          IF ((II(2) .AND. MASK) .EQ. 0)  ! Fortran indices start at 1, not 0.
     >      WRITE (6,100) II(2)
        ENDDO
100     FORMAT (' '/,' Sine in hex :', Z8.8)

        CALL EXIT
        END

The "CALL EXIT" at the bottom is optional (more-or-less). A "STOP" statement
would do just as well.  Also, there are a variety of ways of doing the FORMAT
statement; I often write it as an explicit string in the WRITE statement thus
doing away with the label 100 and the FORMAT statement altogether.  By the
way, using non-integer loop variables is generally to be dicouraged due to
possible round-off errors in calculating the number of trips through the loop. 

Here's an alternative coding, just by way of example:

        PROGRAM TEST1

        IMPLICIT NONE   ! Force all variables to be explicitly declared

        STRUCTURE /SS/
          UNION
            MAP
              INTEGER*4 I(2)
            END MAP
            MAP
              REAL*8    D(2)
            END MAP
          END UNION
        END STRUCTURE

        RECORD /SS/ DI

        INTEGER*4 I
        REAL*4    F
        REAL*8    D

        DO I=1,100000
          F = (I-1)*0.000001
          D = F                 ! Compiler "doubles" F automatically
          DI.D = SIN(D)

          IF ((DI.I(2).AND.'1F800000'X) .EQ. 0)
     >      WRITE (6,'('' '',/,'' Sine in hex :'', Z8.8)') DI.I(2)
        ENDDO

        STOP
        END


The shortest version might be:

        PROGRAM TEST3

        INTEGER             II(2), I
        DOUBLE PRECISION    DI
        EQUIVALENCE        (II,DI)

        DO I=1,100000
          DI = SIN(DBLE(FLOAT(I-1)*0.000001))
          IF ((II(2).AND.'1F800000'X) .EQ. 0)
     >      WRITE (6,'('' '',/,'' Sine in hex :'', Z8.8)') II(2)
        ENDDO

        STOP
        END


Note that in TEST2 and TEST3, the explicit format in the WRITE statement
uses doubled singled-quote marks to get an explicit single-quote in the
quoted string.  Also note that the formate Z8.8 prints the number in hex
with leading zeros; "Z" without "8.8" would not print the leading zeros.

    Questions anyone? :-)

		Cheers, Ken
--
 Dr. Kenneth H. Fairfield    |  Internet: Fairfield@Slacvx.Slac.Stanford.Edu
 SLAC, P.O.Box 4349, MS 98   |  DECnet:   45537::FAIRFIELD (45537=SLACVX)
 Stanford, CA   94309        |  BITNET    Fairfield@Slacvx
 ----------------------------------------------------------------------------
 These opinions are mine, not SLAC's, Stanford's, nor the DOE's...