Homework Assignment 2

Here are my solutions to homework 2. Please let me know if you find an error!


Problem 5.8 in Austin/Chancogne.

The problem statement does not contain an initial velocity -- I assume readers will choose one that is reasonable (e.g., 200 m/sec).

My C code is as follows:

/*
 *  ======================================================================
 *  prog_projectile.c : Compute flight time and range of projectile.
 *
 *  Note -- The variables in this problem are:
 *
 *          dVelocity    : Launch velocity of projectile (m/sec).
 *          iLaunchAngle : Launch angle (in degrees).
 *          dGravity     : Acceleration due to gravity (m/sec/sec).
 *
 *  Written By : M. Austin                                  September 1995
 *  ======================================================================
 */

#include <stdio.h>
#include <math.h>

int main( void ) {
double dRange,  dFlightTime, dTheta, dVelocity;
double dGravity = 9.81;                      /* gravity = 9.81 m/sec/sec */
int   iLaunchAngle, ii;

   /* [a] : Initialize and print projectile valiables */

   dVelocity = 200;
   printf("\n");
   printf("Projectile : Launch Velocity = %f (m/sec)\n\n", dVelocity );

   /* [b] : Initialize Reliability for Network Components */

   printf("=============================================\n" );
   printf("     Launch           Flight                 \n" );
   printf("Angle (deg)       Time (sec)        Range (m)\n" );
   printf("============================================= \n\n" );

   for (iLaunchAngle = 0; iLaunchAngle <= 90; iLaunchAngle = iLaunchAngle + 5) {
        dTheta = (iLaunchAngle/90.0)*M_PI/2;

        dFlightTime = 2*dVelocity*sin(dTheta)/dGravity;
        dRange      = dVelocity*dVelocity*sin(2.0*dTheta)/dGravity;

        printf("    %7d ",   iLaunchAngle );
        printf(" %15.3f ",   dFlightTime );
        printf(" %15.6f \n", dRange );
   }
}

Example. This program generates the output:

Projectile : Launch Velocity = 200.000000 (m/sec)

=============================================
     Launch           Flight                 
Angle (deg)       Time (sec)        Range (m)
============================================= 

          0            0.000         0.000000 
          5            3.554       708.045577 
         10            7.080      1394.577547 
         15           10.553      2038.735984 
         20           13.946      2620.948459 
         25           17.232      3123.524743 
         30           20.387      3531.194307 
         35           23.387      3831.570319 
         40           26.209      4015.526006 
         45           28.832      4077.471967 
         50           31.235      4015.526006 
         55           33.401      3831.570319 
         60           35.312      3531.194307 
         65           36.954      3123.524743 
         70           38.316      2620.948459 
         75           39.385      2038.735984 
         80           40.155      1394.577547 
         85           40.620       708.045577 
         90           40.775         0.000000 

Notice that the maximum range occurs for launch angle 45 degrees (as expected).


Problem 5.9 in Austin/Chancogne.

/* 
 *  =================================================================== 
 *  prog_sqroot1.c : Square root approximation routine
 * 
 *  Written By : David Mazzoni                             October 1996 
 *  =================================================================== 
 */

 #include <stdio.h>
 #include <math.h>

 int main() {
 float fValue;                   /* Value to find the square root of */
 float fPrev;                    /* Value from last/previous calculation */
 float fSqRoot;
 const float kfEpsilon = .0001F; /* Desired Accuracy */

    /* [a] : Prompt user for number */

    printf( "\nEnter a value to find the square root of -->" );
    scanf( "%f", &fValue );

    /* [b] : Check that value is greater than zero */

    if( fValue <= 0 ) {
        printf("ERROR >> Input value must be greater than zero \n");
        printf("ERROR >> Please try again                      \n");
        exit (1);
    }

    /* [c] : Compute square root */

    fSqRoot = fValue / 2.0F; /* Initial estimate */
    do {
       fPrev = fSqRoot;
       fSqRoot = 0.5F * ( fPrev + fValue / fPrev );
    } while( fabs( fSqRoot - fPrev ) > kfEpsilon );

    /* [d] : Print approximate value of square root */

    printf( "The approximate square root of %g is %g\n",
            fValue, fSqRoot );

    return 0;
}


Problem 5.10 in Austin/Chancogne.

/*
 *  =======================================================================
 *  prog_bits_print.c : Compute and print bitwise logical and bitwise shift
 *                      operations.
 *
 *  Written By : Mark Austin                                   October 1996
 *  =======================================================================
 */

#include <stdio.h>
#include <limits.h>

/*
 *  ========================================================
 *  Print bit pattern within a byte 
 *
 *  Input  : unsigned char -- details of byte to be printed.
 *  Output : void.
 *  ========================================================
 */

void PrintBitsInByte ( unsigned char ucByte ) {
int iBitCount;

    for (iBitCount = CHAR_BIT - 1; iBitCount >= 0; iBitCount-- ) {
         printf("%c", (ucByte & (1 << iBitCount) ? '1' : '0'));
    }
    printf("\n");
}

/*
 *  ========================================
 *  Test program for printing bit operations 
 *  ========================================
 */

int main( void ) {
unsigned char ucChar1 = 'A';
unsigned char ucChar2 =   9;

  /* [a] : Setup and print byte variables */

  printf( "The binary value of %3d is : ", ucChar1 );
  PrintBitsInByte ( ucChar1 );
  printf( "The binary value of %3d is : ", ucChar2 );
  PrintBitsInByte ( ucChar2 );

  /* [b] : Compute and print bitwise logical operations */

  printf("\n");
  printf("Exercise bitwise logical operations\n\n");

  printf( "The binary value of (%3d | %3d) is : ", ucChar1, ucChar2 );
  PrintBitsInByte ( ucChar1 | ucChar2 );
  printf( "The binary value of (%3d & %3d) is : ", ucChar1, ucChar2 );
  PrintBitsInByte ( ucChar1 & ucChar2 );
  printf( "The binary value of (%3d ^ %3d) is : ", ucChar1, ucChar2 );
  PrintBitsInByte ( ucChar1 ^ ucChar2 );

  /* [c] : Compute and print bitwise shift operations */

  printf("\n");
  printf("Exercise bitwise shift left operations\n\n");

  printf( "The binary value of (%3d << 1) is : ", ucChar1 );
  PrintBitsInByte ( ucChar1 << 1 );
  printf( "The binary value of (%3d << 2) is : ", ucChar1 );
  PrintBitsInByte ( ucChar1 << 2 );
  printf( "The binary value of (%3d << 3) is : ", ucChar1 );
  PrintBitsInByte ( ucChar1 << 3 );

  printf("\n");
  printf("Exercise bitwise shift right operations\n\n");

  printf( "The binary value of (%3d >> 1) is : ", ucChar1 );
  PrintBitsInByte ( ucChar1 >> 1 );
  printf( "The binary value of (%3d >> 2) is : ", ucChar1 );
  PrintBitsInByte ( ucChar1 >> 2 );
  printf( "The binary value of (%3d >> 3) is : ", ucChar1 );
  PrintBitsInByte ( ucChar1 >> 3 );
}

Example. The output from this program is as follows:

The binary value of  65 is : 01000001
The binary value of   9 is : 00001001

Exercise bitwise logical operations

The binary value of ( 65 |   9) is : 01001001
The binary value of ( 65 &   9) is : 00000001
The binary value of ( 65 ^   9) is : 01001000

Exercise bitwise shift left operations

The binary value of ( 65 << 1) is : 10000010
The binary value of ( 65 << 2) is : 00000100
The binary value of ( 65 << 3) is : 00001000

Exercise bitwise shift right operations

The binary value of ( 65 >> 1) is : 00100000
The binary value of ( 65 >> 2) is : 00010000
The binary value of ( 65 >> 3) is : 00001000


Problem 6.3 in Austin/Chancogne.

Our solution to this problem uses Newton Raphson to compute the roots of the cubic equation describing equilibrium of the sphere in water. We use finite differences to approximate the first and second derivatives of the equation of equilibrium. (Finally, our implementation includes a check for possible divergence of iterates).

/*
 *  ========================================================================
 *  prog_sphere.c -- Use method of Newton-Raphson to compute the depth at
 *                   a sphere of density "rho" sits in water.
 *
 *  Written By : Mark Austin                                    October 1996 
 *  ========================================================================
 */

#include <stdio.h>
#include <math.h>

double NewtonRaphson( double, double, double, double, int );
double dDensity;  /* Global variable for density of sphere */

int main( void ) {
enum { NoPoints = 11 };
double dResponse[NoPoints][2];
double dRoot;
float fStart;
int ii;

   /* [a] : Compute depth of sphere for rho = 0 to rho = 1 */

   for(ii = 1; ii <= NoPoints; ii = ii + 1) {

       /* [a.1] : Empirically adjust starting value for iteration */

       if(ii <= 9)
         fStart = 1.0;
       else 
         fStart = 2.5;

       /* [a.2] : Compute root to equation of equilibrium */

       dDensity = (ii-1)*0.1;
       dRoot = NewtonRaphson( fStart, 0.00001, 0.00001, 0.1, 20 );

       /* [a.3] : Save density and computed depth */

       dResponse[ii-1][0] = dDensity;
       dResponse[ii-1][1] = dRoot; 
   }

   /* [b] : Print results of analysis */

   printf("==================\n");
   printf("Density      [d/r]\n");
   printf("==================\n");

   for(ii = 1; ii <= NoPoints; ii = ii + 1) 
       printf("%7.2f  %9.2f\n", dResponse[ii-1][0], dResponse[ii-1][1]);
} 

/*
 *  =====================================================
 *  Function for equilibrium of sphere floating in water.
 *  =====================================================
 */

double SphereEquilibrium(double dX) {
       return (dX*dX*dX  - 3*dX*dX + 4.0*dDensity);
}

/*
 *  ========================================================================
 *  Use Newton Raphson to Compute Root of Equation
 *
 *  Note : First and second derivatives are estimated via finite differences
 *       : We use the second derivative in test for convergence criteria
 *
 *  Input  : dX0        -- Initial Guess at Root.
 *         : dDelta     -- Convergence criteria for change in x values
 *         : dEpsilon   -- Convergence criteria for y-values.
 *         : dIncrement -- Increment for derivative estimate
 *         : iMaxIter   -- Maximum number of iteration
 *  Output : dXnew      -- Root of the equation   
 *  ========================================================================
 */

double NewtonRaphson( double dX0, double dDelta, double dEpsilon,
                      double dIncrement, int iMaxIter) {

double dXn, dXnew, dYn, dAbsXn, dAbsXndiff, dAbsYn;
double d1Derivative, d2Derivative;
int iCount = 0;

   /* [a] : Initialize variables for iteration */

   dXn        = dX0;
   dAbsXn     = fabs(dXn);
   dAbsXndiff = fabs(dXn - dXnew);
   dAbsYn     = fabs( SphereEquilibrium(dXn) );

   /* [b] : Compute Newton-Raphson Iterates */
 
   while((dAbsYn > dEpsilon) && (iCount <= iMaxIter) &&
         (dAbsXndiff > dDelta*dAbsXn) ) {

      /* [b.1] : Compute finite difference estimates of first and  */
      /*         second derivates                                  */

      d1Derivative = ( SphereEquilibrium(dXn + dIncrement) - 
                       SphereEquilibrium(dXn - dIncrement) )/(2.0*dIncrement);
      d2Derivative = ( SphereEquilibrium(dXn + dIncrement) -
                       2.0*SphereEquilibrium (dXn)
                     + SphereEquilibrium(dXn - dIncrement) )/pow(dIncrement, 2.0);

      /* [b.2] : If the sufficient condition for the algorithm to convergence */
      /*         is not satisfied, send error message and exit program.       */

      if ( fabs( SphereEquilibrium(dXn))*d2Derivative >= pow(d1Derivative, 2.0)) {
         printf("ERROR >> Algorithm may not converge for the starting value.\n");
         printf("ERROR >> Please choose another starting value.\n\n");
         exit(1);
      }  

      /* [b.3] : Compute update in Newton-Raphson iteration */

      dXnew  = dXn - SphereEquilibrium(dXn)/d1Derivative;
      dAbsXn = fabs(dXn);
      dAbsXndiff = fabs(dXnew - dXn);
      dAbsYn     = fabs( SphereEquilibrium (dXn) );
        
      iCount += 1;
      dXn = dXnew; 
   }

   return dXn;
}

Example. The program output is as follows:

    ==================
    Density      [d/r]
    ==================
       0.00      -0.00
       0.10       0.39
       0.20       0.57
       0.30       0.73
       0.40       0.87
       0.50       1.00
       0.60       1.13
       0.70       1.27
       0.80       1.43
       0.90       2.35
       1.00       2.00


Problem 6.5 in Austin/Chancogne.

/*
 *  ==============================================================
 *  prog_dectobinary.c -- Convert an integer in base 10 to base 2.
 *
 *  Written By: David Mazzoni and Mark Austin         October 1996
 *  ==============================================================
 */

#include <stdio.h>
#include <math.h>

/* 
 *  ===============================================
 *  Return the power of iBase to iPow for iPow >= 0
 *  ===============================================
 */

int power( int iBase, int iPow ) {
int iMult = 1;

  while( iPow > 0 ) {
    iMult *= iBase;
    iPow--;
  }
  return iMult;

}

int main ( void ) {
int iVal;
int iDig;
  
  printf("Enter a decimal value from 0..255 -->" );
  scanf( "%d%*c", &iVal );  
  printf("\nThe entered number is %i\n", iVal );

  for( iDig = 7; iDig >= 0; iDig-- ) {
    if( iVal / power( 2, iDig ) == 1 )
      putchar('1');
    else
      putchar('0');
    iVal = iVal % power( 2, iDig );
  }
    
  printf( "\nHit ..." );
  getchar();
  return 0;
}


Developed in March 1999 by Mark Austin
Last Modified March 10, 1999
Copyright © 1999, Mark Austin, Department of Civil Engineering, University of Maryland