BUG: tan() Function Returns Values with Wrong Sign

ID: Q111067

1.00 1.50 WINDOWS kbprg kbbuglist

The information in this article applies to:

SYMPTOMS

In Visual C++ 1.0 and 1.5, calling the run-time tan() function with values between -90 and +90 degrees (between approximately -1.57 and 1.57 radians) may return a value with an incorrect sign. Values that would normally be negative (-90 to 0 degrees) are positive, while values that would normally be positive (0 to 90 degrees) are negative.

This problem occurs only on systems without math coprocessors, or with a NO87 environment variable set to any value.

RESOLUTION

Currently, the only method to work around this problem is to construct a wrapper function, for example a fixtan() function, that either returns sin()/cos() or calls tan(), checks the sign of the returned value, and corrects it if needed before returning. A convenient way to implement the correction is to use a #define, such as

   #define tan fixtan

after math.h is included [and after fixtan()'s definition] to automatically replace all calls to tan() with calls to fixtan().

An example of such a wrapper function is included in the sample code at the end of this article.

STATUS

Microsoft has confirmed this to be a problem in Visual C++ for Windows, versions 1.0 and 1.5. We are researching this problem and will post new information here in the Microsoft Knowledge Base as it becomes available.

This is not a problem with Visual C++ 32-bit Edition.

MORE INFORMATION

Sample Code

/* Compile options needed: none
** ** This demonstrates incorrect results from the ** tan() function and how to work around them. ** ** To reproduce problem on systems with coprocessors enter ** SET NO87=TRUE ** from the command line before running this program, ** and comment out the "#define tan fixtan" line in code.
*/ 

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

// Note that this could also be a macro replacing tan().
double fixtan( double dblVal ) {
        return sin(dblVal)/cos(dblVal);
}

// Comment out the following #define to demonstrate error.
#define tan fixtan

void main(void)
{
   printf("Tangent of 0.8268 = %f\n", tan(0.8268) );
   printf("Cosine of 2.1 = %f\n", cos(2.1) );
   printf("Tangent of 0.8268 = %f\n", tan(0.8268) );
}

Additional reference words: 1.00 1.50 KBCategory: kbprg kbbuglist KBSubcategory: CRTIss

Keywords          : kb16bitonly kbCRT kbVC kbbuglist
Version           : 1.00 1.50
Platform          : WINDOWS

Last Reviewed: July 22, 1997