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; }