BUG: tan() Function Returns Values with Wrong Sign

Last reviewed: July 18, 1997
Article ID: Q111067
1.00 1.50 WINDOWS kbprg kbbuglist

The information in this article applies to:

  • The C Run-time (CRT), included with: Microsoft Visual C++ for Windows, versions 1.0 and 1.5

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 : CRTIss kb16bitonly kbbuglist kbprg
Version : 1.00 1.50
Platform : WINDOWS


THE INFORMATION PROVIDED IN THE MICROSOFT KNOWLEDGE BASE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. MICROSOFT DISCLAIMS ALL WARRANTIES, EITHER EXPRESS OR IMPLIED, INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL MICROSOFT CORPORATION OR ITS SUPPLIERS BE LIABLE FOR ANY DAMAGES WHATSOEVER INCLUDING DIRECT, INDIRECT, INCIDENTAL, CONSEQUENTIAL, LOSS OF BUSINESS PROFITS OR SPECIAL DAMAGES, EVEN IF MICROSOFT CORPORATION OR ITS SUPPLIERS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. SOME STATES DO NOT ALLOW THE EXCLUSION OR LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES SO THE FOREGOING LIMITATION MAY NOT APPLY.

Last reviewed: July 18, 1997
© 1998 Microsoft Corporation. All rights reserved. Terms of Use.