C      Programmer: Dan Gritsko

C      Course: CS 430

C      Date Due: September 13, 2007

C      Language: FORTRAN

C      Compiler used: FORCE2.08

C      Source Filename: Program2Integers.f

C      Executable Filename (if any) or None: None

C      Professor: Elizabeth Adams


C      Purpose: This program takes a single integer from somewhere in
C         the range of 1 to 32767 and converts this number to binary.
C         The binary representation of this number is then displayed
C         on the screen with an appropriate label.

C      Input: This program takes a single input from the user: any
C         base 10 integer from 1 to 32767. If the input entered by the
C         user is not a string of digits, the program will display an
C         error message and terminate prematurely. The program will
C         also display a message and terminate if the input is out
C         of range (less than 1 or greater than 32767).

C      Output: This program will output both the original (base 10)
C         integer that was input by the user, as well as the converted
C         (base 2) representation of this value.

C      General Comments: The hardest part of this program was the conversion
C         algorithm from base 10 to base 2. The way I solved the issue was
C         by appending a zero to a string of characters if the current value
C         was divisible by two, and appending a one otherwise. Then I divided
C         the value in half and repeated the process until the value reached
C         zero. The resulting sequence represented the original integer in
C         base 2, however it was in reverse order. I wrote a subroutine to
C         reverse a certain number of elements in an array and used it to
C         correct the order of 0s and 1s.

C      Language Information:
C         All the variables in this program are either of type character
C         or of type integer. All variables of type character are
C         declared using the word CHARACTER. Integer declarations are
C         unnecessary, since variable names beginning with I-N are
C         assumed by the compiler to be of data type integer.
C         = is the assignment operator.
C         + is the addition operator.
C         - is the subtraction operator.
C         / is the division operator.
C         DIMENSION statement is used to define arrays.
C         CALL statement is used to call subroutines.
C         RETURN statement is used to return from functions or subroutines.
C         DO statement is used to declare DO loops. First value after DO
C            statement is the label for the end of the loop. Next value
C            is the name of the loop control value. Next comes an equals
C            sign, then the start value of the loop control value followed
C            by a comma. Next is the end value for the loop control value,
C            followed by a second comma. Finally, the modification value
C            defines how much the loop control value should be changed
C            after each iteration of the loop.
C         CONTINUE statement is non-executable and is used in conjunction
C            with a label to mark the end of a DO loop.
C         WRITE statement is the output statement.
C         6 in WRITE(6,_) is the default output device.
C         The numbers after 6, in the WRITE statements are labels for
C            FORMAT statements.
C         READ statement is the input statement.
C         5 in READ(5,_) is the default input device.
C         The numbers after 5, in the READ statements are lables for
C            FORMAT statements.
C         FORMAT statements are labeled and non-executable, and can
C            therefore be placed anywhere in the program.
C         All WRITE statements should have a 1X as the first element in
C            the format list.
C         The A format in a format list indicates a string of characters
C            is to be output, the F format in a format list indicates
C            a real number is to be output.
C         The 1st number after the F in the FORMAT statement indicates
C            the 10 width of the variable.
C         The 2nd number after the F in the FORMAT statement indicates
C            number of places after the decimal point.
C         STOP statement ends the program execution.
C         END statement marks the end of a compilation unit.

C234567890

C       Declare an array of characters to store the binary representation
C       of the integer. The array has 16 indexes because 16 bits are needed
C       to represent 32767 in binary, and 32767 is the maximum valid input.
        CHARACTER CHARS(16)

C       Prompt the user for an integer.
        WRITE(6,10) 'Enter a base 10 integer:'
        
C       Read in an integer from the keyboard, and go to label 30 if
C       there was an error in the input (usually happens when characters
C       other than 0-9 were entered).
        READ(5,20,ERR = 30) I
        

C       Check to ensure that the input was within the correct range. If
C       it was, go to the next portion of the program. If it wasn't,
C       display an error message, then go to the end of the program.
        IF ((I .GE. 1) .AND. (I .LE. 32767)) GOTO 1
        WRITE(6,10) 'Input must be within range of 1 to 32767'
        GOTO 99

C       Write the original base 10 integer back to the screen.
   1    WRITE(6,11) I

C       This integer will keep track of how many bits it takes to
C       represent the integer in binary.
        NUM = 1
        
C       Create a binary representation of the integer by filling the
C       CHARS array with 0's and 1's.
        DO 100 L = 1,16
C          First, set the current index of the array to a blank space.
           CHARS(L) = ' '
C          Check to see if the conversion is finished.
           IF (I .LT. 1) GO TO 100
C          Check to see if the current number is not divisible by 2
           IF (MOD(I, 2) .EQ. 1) GO TO 102
C          If the current number is divisible by 2, set the current
C          index of the array to the character '0'.
           CHARS(L) = '0'
           GO TO 101
C          If the current number is not divisible by 2, set the current
C          index of the array to the character '1'.
  102      CHARS(L) = '1'
C          Divide the number in half. Since it's an integer, everything
C          to the right of the decimal place will be truncated.
  101      I = I / 2
C          Increase the count of indices in the array that contain
C          either a 0 or a 1
           NUM = NUM + 1
  100   CONTINUE
  
C       Reverse the order of the elements in the character array so that
C       the binary number is represented correctly (because of the way
C       the conversion algorithm works, the order of the 0s and 1s in
C       the array must be corrected).
        CALL REVERSE(CHARS, NUM)

C       Write the contents of the array to the screen; it should now
C       be a string of 0s, 1s, and blank spaces which represent the
C       converted integer
        WRITE(6,12) CHARS
        
C       If the program reaches this point, it has executed without
C       any errors and should skip to the end of the program (i.e.,
C       over the error message at label 30).
        GO TO 99
        
C       Error message which will be displayed if the user enters incorrect
C       input (non-digit characters).
   30   WRITE(6,10) 'Had an error in the input data'

C       Output format statements.
   10   FORMAT(1X, A40)
   11   FORMAT(1X, 'The base 10 value of the input is: ', I5)
   12   FORMAT(1X, 'The base  2 value of the input is: ', 16(A1))

C       Input format statement for reading in the integer.
   20   FORMAT(I5)

C       Stop the execution of the program.
   99   STOP
        END

C       This subroutine requires two parameters - an array of
C          characters CHARS, and an integer NUM representing how many
C          elements of CHARS must be reversed. The subroutine then uses
C          a DO loop to reverse the order of the first NUM elemens in CHARS.
C          Once this operation has completed, the subroutine ends.
        SUBROUTINE REVERSE(CHARS, NUM)
           CHARACTER CHARS(NUM)
           CHARACTER CTEMP
C          Index of the leftmost element to swap.
           ILEFT = 1
C          Index of the rightmost element to swap.
           IRIGHT = NUM - 1

           DO 300 L = 1, NUM
C             If the whole sequence has been reversed, go to the next
C             iteration of the loop.
              IF (ILEFT .GE. IRIGHT) GO TO 301
C             Otherwise, swap the elements at ILEFT and IRIGHT
              CTEMP = CHARS(ILEFT)
              CHARS(ILEFT) = CHARS(IRIGHT)
              CHARS(IRIGHT) = CTEMP
C             Increase ILEFT by one
              ILEFT = ILEFT + 1
C             Decrease IRIGHT by one
              IRIGHT = IRIGHT - 1
  300      CONTINUE

C       Return from subroutine.
  301   RETURN
        END
