Microsoft KB Archive/167750: Difference between revisions

From BetaArchive Wiki
m (Text replacement - ">" to ">")
m (Text replacement - """ to """)
Line 74: Line 74:
     {
     {
         /* Handle errors caused by pow() function.*/  
         /* Handle errors caused by pow() function.*/  
         if(strcmp(except->name,"pow")==0)
         if(strcmp(except->name,"pow")==0)
         {
         {
             switch(except->type)
             switch(except->type)
Line 80: Line 80:
                 case _DOMAIN:
                 case _DOMAIN:
                 {
                 {
                     printf("Domain Error: Argument not in domain.\n");
                     printf("Domain Error: Argument not in domain.\n");
                     return 1;
                     return 1;
                     break;
                     break;
Line 86: Line 86:
                 case _SING:
                 case _SING:
                 {
                 {
                     printf("Singularity Error: Argument singularity "
                     printf("Singularity Error: Argument singularity "
                           "error.\n");
                           "error.\n");
                     return 1;
                     return 1;
                     break;
                     break;
Line 93: Line 93:
                 case _OVERFLOW:
                 case _OVERFLOW:
                 {
                 {
                     printf("Overflow Error: Overflow range error.\n");
                     printf("Overflow Error: Overflow range error.\n");
                     return 1;
                     return 1;
                     break;
                     break;
Line 99: Line 99:
                 case _PLOSS:
                 case _PLOSS:
                 {
                 {
                     printf("Precision Error: Partial loss of "
                     printf("Precision Error: Partial loss of "
                           "significance.\n");
                           "significance.\n");
                     return 1;
                     return 1;
                     break;
                     break;
Line 106: Line 106:
                 case _TLOSS:
                 case _TLOSS:
                 {
                 {
                     printf("Precision Error: Total loss of "
                     printf("Precision Error: Total loss of "
                           "significance.\n");
                           "significance.\n");
                     return 1;
                     return 1;
                     break;
                     break;
Line 113: Line 113:
                 case _UNDERFLOW:
                 case _UNDERFLOW:
       {
       {
                     printf("Underflow Error: The result is too small to "
                     printf("Underflow Error: The result is too small to "
                           "be represented.\n");
                           "be represented.\n");
                     return 1;
                     return 1;
                     break;
                     break;
Line 120: Line 120:
                 default:
                 default:
                 {
                 {
                     printf("Unknown Error Occurred While Performing Math "
                     printf("Unknown Error Occurred While Performing Math "
                           "Operation.\n");
                           "Operation.\n");
                     return 1;
                     return 1;
                     break;
                     break;
Line 147: Line 147:
     /*Note that errno is not set properly & _matherr() is called.*/  
     /*Note that errno is not set properly & _matherr() is called.*/  
     if (errno != 0)
     if (errno != 0)
         printf("ERROR! Errno: %i\n",errno);
         printf("ERROR! Errno: %i\n",errno);
     else
     else
         printf("pow( %e, %e ) = %f\n", x, y, z);
         printf("pow( %e, %e ) = %f\n", x, y, z);
   }
   }
                 </pre>
                 </pre>
Line 174: Line 174:


</div>
</div>
However, an overflow does set errno to the value of 34 indicating &quot;Result too large&quot;. When an underflow occurs, the returned value is 0.
However, an overflow does set errno to the value of 34 indicating "Result too large". When an underflow occurs, the returned value is 0.


</div>
</div>

Revision as of 11:03, 21 July 2020

Knowledge Base


Article ID: 167750

Article Last Modified on 9/23/2003



APPLIES TO

  • The C Run-Time (CRT)
  • Microsoft Visual C++ 5.0 Professional Edition
  • Microsoft Visual C++ 6.0 Professional Edition
  • Microsoft Visual C++ 5.0 Enterprise Edition
  • Microsoft Visual C++ 6.0 Enterprise Edition
  • Microsoft Visual C++ 6.0 Standard Edition
  • Microsoft Visual C++ .NET 2003 Standard Edition
  • Microsoft Visual C++ .NET 2002 Standard Edition



This article was previously published under Q167750

SYMPTOMS

The pow() function does not set the errno variable to indicate that an underflow condition has occurred.

RESOLUTION

A potential solution is to check the base of the number that is being raised to a power and check the result of the pow() function. By customizing the _matherr() function, the underflow condition can be trapped and you can display an error message. The program below demonstrates this workaround.

    #include <stdio.h>
    #include <math.h>
    #include <ERRNO.H>
    #include <string.h>
    extern int errno;

    /* The _matherr routine can be customized to handle the specific
        underflow problem that is encountered.  See online help for
        more information on _matherr().
    */ 
    int _matherr( struct _exception *except )
    {
        /* Handle errors caused by pow() function.*/ 
        if(strcmp(except->name,"pow")==0)
        {
            switch(except->type)
            {
                case _DOMAIN:
                {
                    printf("Domain Error: Argument not in domain.\n");
                    return 1;
                    break;
                }
                case _SING:
                {
                    printf("Singularity Error: Argument singularity "
                           "error.\n");
                    return 1;
                    break;
      }
                case _OVERFLOW:
                {
                    printf("Overflow Error: Overflow range error.\n");
                    return 1;
                    break;
                }
                case _PLOSS:
                {
                    printf("Precision Error: Partial loss of "
                           "significance.\n");
                    return 1;
                    break;
                }
                case _TLOSS:
                {
                    printf("Precision Error: Total loss of "
                           "significance.\n");
                    return 1;
                    break;
      }
                case _UNDERFLOW:
      {
                    printf("Underflow Error: The result is too small to "
                           "be represented.\n");
                    return 1;
                    break;
                }
                default:
                {
                    printf("Unknown Error Occurred While Performing Math "
                           "Operation.\n");
                    return 1;
                    break;
      }
       }
        }
        else
            return 0;  /* non-error condition */ 
    }

    void main(void)
    {

    double x = -1.0e+307;
    double y = -1.0e+307;
    double z;

    z = pow(x,y);

    /*
    Check for error conditions.  _matherr() is automatically
    called should there be a math related error.
    */ 

    /*Note that errno is not set properly & _matherr() is called.*/ 
    if (errno != 0)
        printf("ERROR! Errno: %i\n",errno);
    else
        printf("pow( %e, %e ) = %f\n", x, y, z);
   }
                

STATUS

Microsoft has confirmed that this is a bug in the Microsoft products that are listed at the beginning of this article.

MORE INFORMATION

The help topic for pow() states:

No error message is printed on overflow or underflow.


However, an overflow does set errno to the value of 34 indicating "Result too large". When an underflow occurs, the returned value is 0.

Keywords: kbbug KB167750