home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c100 / 3.ddi / STARTUP.ZIP / EXAMPLES / FPMATH / MATHERR.C < prev   
Encoding:
C/C++ Source or Header  |  1990-09-01  |  3.0 KB  |  117 lines

  1. /*
  2. //        MATHERR.C    Sample error handling routine for extrinsic functions
  3. //                        in a ROM environment.  This code should be customized
  4. //                        for a particular application and then replace the
  5. //                        matherr() function supplied by Microsoft in the
  6. //                        applicable run-time library.
  7. //    
  8. //        Copyright (C) 1988, 1989 Paradigm Systems.  All rights reserved.
  9. //
  10. //        The _matherr() function is provided to interface to matherr().  It is
  11. //        the responsibility of matherr() to handle all exceptions since except
  12. //        for setting errno, _matherr() has no other impact and will return to
  13. //        the caller with the result to be used.
  14. //
  15. */
  16.  
  17. #include    <stddef.h>
  18. #include    <stdlib.h>
  19. #include    <string.h>
  20. #include    <math.h>
  21. #include    <float.h>
  22.  
  23.  
  24. double    _matherr(why, fun, arg1p, arg2p, retval)
  25. _mexcep    why ;
  26. char        *fun ;
  27. double    *arg1p, *arg2p ;
  28. double    retval ;
  29. {
  30.     struct    exception    e ;
  31.  
  32.     /* Initialize the exception structure for the call to matherr() */
  33.     e.type = why ;
  34.     e.name = fun ;
  35.     e.arg1 = *arg1p ;
  36.     e.arg2 = *arg2p ;
  37.     e.retval = retval ;
  38.  
  39.     /* Call matherr() and abort if it can't handle the exception */
  40.     if (matherr(&e) == 0)   {
  41.         switch (why)   {
  42.             case DOMAIN:
  43.             case SING:
  44.                 errno = EDOM ;
  45.                 break ;
  46.                 
  47.             case OVERFLOW:
  48.             case UNDERFLOW:
  49.             case TLOSS:
  50.             case PLOSS:
  51.                 errno = ERANGE ;
  52.                 break ;
  53.         }
  54.     }
  55.  
  56.     /* Return the value to be used */
  57.     return    e.retval ;
  58. }
  59.  
  60.  
  61. /*
  62. //        This version of matherr() has been modified to return a HUGE_VAL that
  63. //        can be held in type float.  This is done to prevent the functions such
  64. //        as exp() and log() from returning the default of HUGE_VAL which will
  65. //        cause a floating point overflow exception when it is assigned to a float
  66. //        variable.
  67. //
  68. //        matherr() should be customized for the particular application.  This
  69. //        example show the general means to look for specific exception conditions
  70. //        and handle them in a manner consistent with the application.
  71. //    
  72. //        This version will in some cases correct the fault, display an error
  73. //        message and return.
  74. */
  75.  
  76. int    matherr(x)
  77. struct    exception    *x ;
  78. {
  79.     int    code = 0 ;        /* 0 if matherr() can't handle the exception */
  80.  
  81.     switch (x->type)   {
  82.         case DOMAIN:
  83.             if (stricmp(x->name, "exp") == 0 || strnicmp(x->name, "log", 3) == 0)   {
  84.                 x->retval = FLT_MAX * (x->retval < 0.0 ? -1.0 : 1.0) ;
  85.                 code = 1 ;
  86.             }
  87.             else if (stricmp(x->name, "sqrt") == 0)   {
  88.                 x->retval = sqrt(fabs(x->arg1)) ;
  89.                 code = 1 ;
  90.             }
  91.             break ;
  92.   
  93.         case SING:
  94.             if (stricmp(x->name, "exp") == 0 || strnicmp(x->name, "log", 3) == 0)   {
  95.                 x->retval = FLT_MAX * (x->retval < 0.0 ? -1.0 : 1.0) ;
  96.                 code = 1 ;
  97.             }
  98.             break ;
  99.         
  100.         case OVERFLOW:
  101.             if (stricmp(x->name, "exp") == 0 || strnicmp(x->name, "log", 3) == 0)   {
  102.                 x->retval = FLT_MAX * (x->retval < 0.0 ? -1.0 : 1.0) ;
  103.                 code = 1 ;
  104.             }
  105.             break ;
  106.         
  107.         case PLOSS:
  108.         case TLOSS:
  109.         case UNDERFLOW:
  110.         default:
  111.             break ;
  112.     }
  113.  
  114.     /* Return the code showing the exception has been handled */
  115.     return    code ;
  116. }
  117.