/* * ====================================================================== * This program demonstrates: * * [a] - Use of structures and unions. * [b] - Error checking for range and domain of mathematical functions. * ====================================================================== * Copyright (C) 1993-96 by Mark Austin and David Mazzoni. * * This software is provided "as is" without express or implied warranty. * Permission is granted to use this software on any computer system, * and to redistribute it freely, subject to the following restrictions: * * 1. The authors are not responsible for the consequences of use of * this software, even if they arise from defects in the software. * 2. The origin of this software must not be misrepresented, either * by explicit claim or by omission. * 3. Altered versions must be plainly marked as such, and must not * be misrepresented as being the original software. * 4. This notice is to remain intact. * * Written By : M. Austin and D. Mazzoni January 1994 * ====================================================================== */ #include #include #include #include #include "miscellaneous.h" /* * ----------------------------------------------------------------- * Declare a structure containing a name, union of functions, and an * argument count for the function held in the union. Structure is * setup to handle functions with 1, 2, and 3 arguments. * ----------------------------------------------------------------- */ typedef struct funcStruct { char * cpName; union uFunc { double (*func1Arg)( double dX ); double (*func2Arg)( double dX1, double dX2 ); double (*funcFuncArg) ( double (*func)(double dX), double dX ); } uFunc; int iNArgs; } funcStruct; /* Declare functions assignable to the structure's union */ extern int errno; double errorCheck( double , char * ); double mySqrt( double ); double myPower( double , double ); void initTable( funcStruct * spLookupTable ); int main( void ) { funcStruct sTest[4]; /* [a] : Initialize lookup table */ initTable( sTest ); /* [b] : Test functionality of lookup table */ printf("\n"); printf("Test Functions in Lookup Table \n\n"); printf( sTest[0].cpName, 2.0, sTest[0].uFunc.func1Arg( 2.0 ) ); printf( sTest[1].cpName, 2.0, 4.0, sTest[1].uFunc.func2Arg( 2.0, 4.0 ) ); printf( sTest[2].cpName, 3.0, sTest[2].uFunc.func1Arg( 3.0 ) ); printf( sTest[3].cpName, 3.0, sTest[3].uFunc.funcFuncArg( mySqrt , 3.0 ) ); /* [c] : Run examples with range and domain errors */ printf("\n"); printf("Simulate IEEE Floating Point Error Diagnostics \n\n"); printf( sTest[3].cpName, -3.0, sTest[3].uFunc.funcFuncArg( mySqrt , -3.0 ) ); printf( sTest[1].cpName, 10.0, 1000.0, sTest[1].uFunc.func2Arg( 10.0, 1000.0 ) ); } /* * ----------------------------- * Define Mathematical functions * ----------------------------- */ double mySqrt( double dX ) { return errorCheck( sqrt( dX ), "sqrt"); } double myPower( double dBase, double dExp ) { return errorCheck( pow( dBase, dExp ), "power" ); } double myCubed( double dX ) { return errorCheck( pow( dX , 3.0 ), "myCubed" ); } double myFunc( double (* fupFunc)( double dX), double dX ) { return errorCheck( fupFunc( dX ), "my function" ); } /* * ------------------------------------------------------------ * Check Domain and Range of Arguments to Mathematical Function * ------------------------------------------------------------ */ double errorCheck( double dX, char *cpMessage) { if(errno == EDOM) { printf("ERROR : %s", "argument out of domain\n", cpMessage ); errno = 0; } else if(errno == ERANGE) { printf("ERROR : %s", "result out of range \n", cpMessage ); errno = 0; } return (dX); } /* * ----------------------------- * Initialize Lookup Table * ----------------------------- */ void initTable( funcStruct * spLookupTable ) { /* [a] : Initialize the table structure and its unions: */ spLookupTable[0].cpName = "%11.4e squared = %11.4e\n"; spLookupTable[0].uFunc.func1Arg = mySqrt; spLookupTable[0].iNArgs = 1; spLookupTable[1].cpName = "The power of %11.4e to the %11.4e = %11.4e\n"; spLookupTable[1].uFunc.func2Arg = myPower; spLookupTable[1].iNArgs = 2; spLookupTable[2].cpName = "%11.4e cubed = %11.4e\n"; spLookupTable[2].uFunc.func1Arg = myCubed; spLookupTable[2].iNArgs = 3; spLookupTable[3].cpName = "Call of func( mySqrt(%11.4f) ) = %11.4e\n"; spLookupTable[3].uFunc.funcFuncArg = myFunc; spLookupTable[3].iNArgs = 1; }