C       Programmer: Stephen Kalletta
C       Course: CS 430, 2:00 pm class
C       Date Due: September 12, 2007
C       Language: Fortran
C       Compiler used: Force 2.0
C       Source Filename: Programming Assignment two.f
C       Executable Filename: Programming Assignment two.exe
C       Professor: Professor Adams


C       DESCRIPTION OF THE PROGRAM'S PURPOSE:
C       The purpose of this program is broken into two parts.  The
C       first part reads in an integer between 1 and 32767 and prints
C       out its base 2 representation.  The second part reads in a
C       a decimal number (a fraction) and prints out its base 2
C       representation.
C
C       DESCRIPTION OF PROGRAM'S REQUIRED INPUT:
C       Part A requires an integer between 1 and 32767.  This is stored
C       into an INTEGER variable 'J'.  If the number entered is
C       negative or greater than 32767, an error message will be
C       displayed and the program will prompt the question for the
C       correct type of integer.
C
C       Part B requires a decimal between 0 and 1.0.  This is stored in
C       a REAL variable 'A'.  If the number entered is less than 0 or
C       greater than 1, an error message will be displayed and the
C       program will prompt for the corerct type of decimal.  The
C       problem with this implementation is that if a person enters
C       '3.0', the program will give them an error, but if a person
C       enters '3', the program adds its own decimal point infront of
C       the three.
C
C       DESCRIPTION OF PROGRAM'S EXPECTED OUTPUT:
C       The output of this data should contain the original data values
C       and the converted binary numbers.  In the case of Part B, the
C       final binary representation of a decimal is truncated at six
C       decimals, as specified in the program requirements.  This
C       information is stored in INTEGER arrays, with each position
C       keeping track of a individual binary bit.  The order of the bits
C       is kept track by an implementation of a counter. If there is an
C       error in the users input, an error message will be displayed
C       with a prompt asking for the correct data.
C
C       GENERAL COMMENTS ABOUT THE PROGRAM:
C       Before I list individual things, here is some background
C       information about how I implemented this program and why.
C
C       I first implemented this project using an INTEGER for Part A
C       and a REAL for Part B.  These first two implementations can be
C       found in the comments after the end of the final implementation
C       of the program labeled 'INTEGER IMPLEMENTATION' and 'REAL
C       IMPLEMENTATION'.  The INTEGER worked fine, using a formula to
C       create and store the binary representation of the number given
C       by the user. The problem began when using numbers that
C       contained too many bits.  Garbage would be outputed.  For Part B
C       the mathematics behind the REAL worked perfectly. However, the
C       output would display zeros that were not needed to be displayed.
C       Instead of '.1' being displayed for an input of '.5', '.100000'
C       would be displayed.
C
C       Second, I implemented both parts using the DO WHILE Loop and
C       INTEGER ARRAYS.  Overall, this was the best implementation.
C       The mathematics worked perfectly and the output matched what was
C       expected (no extra spaces or zeros). Through email, I found out
C       that DO WHILE Loops were not allowed. I had to change my
C       implementation and use a DO LOOP.  Luckily, I was able to use
C       the same logic for the DO LOOPS that I developed in the
C       implementation using the DO WHILE Loops.  The DO LOOPS
C       automated some of the work for me (a counter, keeping track of
C       where I was in the array.)  The DO WHILE loops are found at
C       the end of the program labeled 'DO WHILE IMPLEMENTATION PART A'
C       and 'DO WHILE IMPLEMENTATION PART B'.
C
C       My final implementation used INTEGER ARRAYS and DO LOOPS.  The
C       Arrays prevented extra zeros from being displayed, and the DO
C       LOOPS followed the specifications of the program. I attempted
C       some sort of ERROR checking.  For Part A, I use the built in
C       ERR to catch any decimal inputs (the number inputted should be
C       an integer.)  After inputed, the integer is checked to make sure
C       it meets the requirements, being in the range of 1 and 32767.
C       This is done using an IF statement.  For Part B, I did not use
C       the built in ERR, because I did not have a set size for the
C       decimal.  I made the format 'F10.6' because there were no
C       specifications.  The output will be truncated at six decimals.
C       Lastly, each part of the program is done individually.  Part A
C       is completed first and then continues to Part B. In the code
C       below, I separated parts A and B with comments so it is clear to
C       follow.
C
C       GENERAL COMMENTS ABOUT THE SYNTAX:
C       -The two arrays storing the binary representation of the
C        inputted data are both declared INTEGER arrays.  N does not
C        need to be delcared since it is INTEGER by default, and
C        DIMENSION could have been used, but I declared it for code
C        consistancy.
C       -All the variables that are reals are labeled beginning with
C        the letters A-H, or O-Z.  They do not need to be delcared
C        because they are defaulted to real.
C       -All integers begin with I-N and are also defaulted to integer
C       -DO LOOPs are used to obtain the final binary representation.
C        The alogrithms used to find the final outputs are found in
C        these two DO LOOPs.
C       -The code 'ERR=29' found in the very first READ statement is an
C        built in error checking method.  If the input does not fit the
C        FORMAT description, the code will travel to the line labeled
C        '29'.  Here, a message is outputted and the user is prompted
C        to input the correct data type.
C       -The GO TO used in the IF statements embedded in the DO LOOPs is
C        used to skip over code that should not be implemented because
C        of the logic in the IF statement.
C       -The GO TO is also used in the Error checking section to refer
C        the user back to the prompting question, sending the code back
C        to the corresponding section (either Part A or Part B)
C       -The GO TO is also used near the end of each code, once the
C        answer has been developed.  These two GO TO's skip over the
C        error messages.  The one at the end of Part A skips to Part B's
C        prompt and the one at the end of Part B ends the program.
C
C        SYNTAX FOUND IN PROGRAM ASSIGNMENT ONE BUT USED IN PA 2:
C       -WRITE is the output statment used in this program. A
C        WRITE(6, _) refers to the default output device.
C       -FORMATS for WRITES start with '1X'
C       -READ is the input statement used in the program.  A READ(5, _)
C        refers to the default input device
C       -The F format indicates a real number is to be output.  The 1st
C        number after the F indicates the width of the variable The 2nd
C        number after the F indicates numer of places after the decimal
C        point
C       -CONTINUE is found at the end of DO LOOPS to send the code back
C        to the beginning of the DO LOOP.
C
C       -Comments through out the program refer to specific lines,
C        variables, and loops





C      **********************************************
C      Part A
C      ARRAY IMPLEMENTATION
C      **********************************************

C      Array N will store the binary for Part A. It is size fifteen
C      because 32767 is the biggest number allowed and its binary
C      representation is 15 bit's of '1'
C      Array X will store the binary for Part B. It is size six because
C      Part B truncates at the sixth decimal place.
       INTEGER N(15)
       INTEGER X(6)

       WRITE(6, 13)

C      This is the prompt for an integer for Part A.
C      This WRITE is labeled '1' because it is referenced by the error
C      check.  If there is an error, a message is displayed and the
C      user is returned to this WRITE statement.
  1    WRITE(6, 15)
       WRITE(6, 14)
 13    FORMAT(1X, 'PART A:', /1X)
 15    FORMAT(1X, 'Enter an integer in the range 1 to 32767 and ')
 14    FORMAT(1X, 'Press Enter:')

C      The ERR will catch any integer that does not fit the FORMAT
C      description labeled '16'.  Its error message is at the WRITE
C      labeled '29'.  The FORMAT is 'I5' because that is how many
C      digit places are in the max number 32767.
       READ(5,16, ERR= 29) J
 16    FORMAT(I5)

C      This is a different error check. By the requirements of the
C      assignment the number must be in the range of 1 to 32767.  If
C      not, the program goes to the line labeled '29' and outputs
C      an error statement.  This line utilizes the GO TO call.  This
C      call sends the control of the program to that line and continues
C      from that line.
       IF((J.GT.32767).OR.(J.LT.1)) GO TO 29

C      Output for the original inputted number. I used 'I5' in the
C      FORMAT because the number will have at most five integer places
C      because the requirements of the program.  The error message will
C      also check for this before this line is even reached.
       WRITE(6,25) J
 25    FORMAT(1X, 'The base 10 value of the input is:', I5)

C      These are the Integer Variables used in the DO LOOP to obtain
C      the binary answer.  The 'K' does mod math to figure out weather
C      this bit will be '1' or '0'. The 'M' keeps track of how many
C      elements in the array are actually storing appropriate data
C      which will be used to display to the user for the output.
       K=0
       M=0
       DO 10 L=1, 15
C        This if statement was not needed for the DO WHILE LOOP.  If J
C        equals 0 the number has finished converting to a binary. It
C        GO TO the continue labeled '10' so nothing is added to the
C        array and allows the DO LOOP to finish.
         IF(J.EQ.0) GO TO 10
          K = MOD(J,2)
          N(L)= K
          J = J/2
          M=M+1
 10    CONTINUE

C      Print out the output.  The array stores the binary digits
C      but must traverse through the array backwards because that is
C      how the formula in the DO LOOP produced the digits.
       WRITE (6,24) (N(I), I= M, 1, -1)
 24    FORMAT(1X, 'The base 2 value of the input is: ', 15(I1))

C      Once this GO TO is reached, everything in the program has worked
C      fine.  Now jump over the Error Message section and continue to
C      Part B which begins at the line labeled '40'
       GO TO 40

C      **ERROR MESSAGE**
C      This is reached only if there is a problem as described before.
C      An error message is produced.  The '/1X' in the FORMAT creates
C      a newline so the output is more organized.  The GO TO sends the
C      code back to the line labeled '1' which is the prompt for a
C      Integer between the required range.
 29    WRITE (6, 20)
 20    FORMAT (1X, ' HAD AN ERROR IN THE INPUT DATA ', /1X)
       GO TO 1
       
C      ************************************************
C      PART B
C      ARRAY IMPLEMENTATION
C      ************************************************

C      This is formated with new lines before and after the string
C      'PART B:' for appearance.  The write is labeled '40', because
C      it is referenced by the GO TO in Part A to jump past the
C      error message section
 40    WRITE(6,50)
 50    FORMAT(1X, /1X, 'PART B:', /1X)

C      This is the prompt for a decimal for Part B.
C      This write is labeled '2' because if there is an error in Part B
C      it will return the user with this prompt after the error
C      message is outputted. There were no clear requirements on the
C      size that the decimal could be.  I have the input truncated at
C      fifteen for more functionality.  The output, however, will be
C      truncated at six.
  2    WRITE(6, 55)
       WRITE(6,54)
       WRITE(6,53)
 55    FORMAT(1X, 'Enter a decimal less than 1.0, greater than 0, and')
 54    FORMAT(1X, 'no more than 15 decimal places, to be converted')
 53    FORMAT(1X, 'to binary then Press Enter: ')

C      Input a decimal. I have it FORMAT as a real to up to 15 decimal
C      points for more functionality.
       READ(5,56) A
 56    FORMAT(F15.15)

C      This is for my error check for Part B.  If the number is less
C      than 0 or greater or equal to 1, then the number will not
C      work using this binary converting algorithm.  The 'GO TO 69'
C      sends the user to the error message.
       IF((A.GE.1).OR.(A.LE.0)) GO TO 69

C      Outputting to the user what the inputted. I have it truncating at
C      six decimals because the binary will truncate at six decimals.
C      This does not affect the REAL 'A' that will travel through the
C      DO LOOP later to create the correct answer.
       WRITE(6,65) A
 65    FORMAT(1X, 'The base 10 value of the input is:', F10.6)

C      This is the DO LOOP that produces the correct binary decimal
C      for the decimal input.  By comparing the REAL number 'B' to the
C      inputted decimal 'A', we decide if the bit is a '1' or '0'.
C      B is continues to be halved because we are trying to get a base
C      2 number.  Once 'B' is smaller than 'A', we know this is a place
C      where we would have a bit equal '1'.  The INTEGER 'I' keeps track
C      of how many digits in the array are used to store data and is
C      referenced later when outputting the binary number.  The
C      INTEGER 'L' keeps track of where in the array to place the
C      correct bit.

       B=1
       I=0
       DO 60 L=1, 6
C       Once A equals 0 the binary conversion is complete.  It continues
C       looping through until the DO LOOP is complete without adjusting
C       the data.
        IF(A.EQ.0) GO TO 60
        X(L) = 0
        B=B/2
        IF(A.GT.B) GO TO 57
        IF(B.GT.A) GO TO 59
  57     A=A-B
         X(L) = 1
  59     I= I+ 1
  60   CONTINUE
  
C      Output the data.  The 'A1' is needed in the FORMAT statement
C      because the array does not store the decimal point and must be
C      hardcoded and outputed by the WRITE statement.  The most I can be
C      is '6', which is the most amount of decimal places required by
C      this program.  I is implemented in the DO LOOP.  The '6(I1)'
C      allows all the digits to be printed out on the same line with no
C      spaces between them.
       WRITE (6,64) '.', (X(M), M = 1,I)
  64   FORMAT(1X, 'The base 2 value of the input is: ', A1, 6(I1))

C      Once this GO TO is reached, everything in the program has worked
C      fine.  Now jump over the Error Message to the line labeled '90'
C      which STOP-s the program, which continues to END-ing the program
       GO TO 90

C      **ERROR MESSAGE**
C      This is reached only if there is a problem as described before.
C      An error message is produced.  The '/1X' in the FORMAT creates
C      a newline so the output is more organized.  The GO TO sends the
C      code back to the line labeled '2' which is the prompt for a
C      decimal between the required range.
 69    WRITE (6, 61)
 61    FORMAT (1X, ' HAD AN ERROR IN THE INPUT DATA ', /1X)
       GO TO  2
       
 90    STOP
       END
       
C      ************************************************************
C      Here I am going to include my original implementations as stated
C      in my GENERAL COMMENTS ABOUT THE PROGRAM. It shows the logic
C      that went through this program and how I ended up with what I
C      have.  Descriptions of each are described above in the
C      GENERAL COMMENTS ABOUT THE PROGRAM section. 'CC' refers to
C      comments I made to myself while developing these implementations.
C      *************************************************************
C
C      INTEGER IMPLEMENTATION
C      CANNOT HAVE MORE THAN 11 BITS
C
C       J=1006
C       M=0
C       I=2
C       L=0
C
C       DO WHILE( J.NE.0)
C          K = MOD(J,I)
C          M = M + ((10**L)*K)
C          J = J/2
C          L = L + 1
C       ENDDO
C
CC      I15 BECAUSE THAT IS THE NUMBER OF BITS FOR THE MAX NUMBER
C       32767

C       WRITE(6,10) M
C 10    FORMAT(1X, I15)
C
C       STOP
C       END
C
C
CC     OUTPUT WHEN LESS THAN 11 BITS:
CC     J = 7
CC                   111
CC
CC      J = 1003
CC
CC              1111101011
CC
CC      J = 32767
CC
CC                 307163591
C
C      ************************************************
C      REAL IMPLEMENTATION
C
C       WRITE(6, 15)
C 15     FORMAT(1X, 'Enter a decimal')
C
C       READ(5,16) A
C 16    FORMAT(F6.6)
C
C       B=1
C       L=1
C       F = 0
C       DO WHILE(A.NE.B)
C         B=B/2
C         IF(A.GT.B) GO TO 17
C         IF(B.GT.A) GO TO 18
C 17       A=A-B
C          P=0-L
C          F= F +(10**P)
C 18       L=L+1
C       ENDDO
C
CC     Default output for testing
C        WRITE (*,*) F
CC  24    FORMAT(1X, F7.6)
C
C
C       STOP
C       END
C
C      ************************************************
C
C      DO WHILE IMPLEMENTATION PART A
CC      ARRAY IMPLEMENTATION
C
C       DO WHILE( J.NE.0)
C          L = L + 1
C          K = MOD(J,I)
C          N(L)= K
C          J = J/2
C       ENDDO

C      ************************************************
C       DO WHILE IMPLEMENTATION PART B
C
C      DO WHILE(A.NE.0 .AND. L.LT.7)
C         N(L) = 0
C         B=B/2
C         IF(A.GT.B) GO TO 17
C         IF(B.GT.A) GO TO 18
C 17       A=A-B
C          N(L) = 1
C 18       L=L+1
C       ENDDO
C
