mathtest.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 329 行
C
329 行
/****************************************************************************
*
* Open Watcom Project
*
* Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
* ========================================================================
*
* This file contains Original Code and/or Modifications of Original
* Code as defined in and that are subject to the Sybase Open Watcom
* Public License version 1.0 (the 'License'). You may not use this file
* except in compliance with the License. BY USING THIS FILE YOU AGREE TO
* ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
* provided with the Original Code and Modifications, and is also
* available at www.sybase.com/developer/opensource.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
* NON-INFRINGEMENT. Please see the License for the specific language
* governing rights and limitations under the License.
*
* ========================================================================
*
* Description: Math library verification test.
*
****************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <float.h>
#ifdef __FPI__
#include <signal.h>
#endif
#ifndef TRUE
#define TRUE 1
#define FALSE 0
#endif
#ifndef PI
#define PI 3.14159265358979323846
#endif
#ifndef E
#define E 2.718281828459045
#endif
#define VERIFY(expr) if(!(expr)) \
printf( "FAIL: %s, line %d\n",#expr,__LINE__ )
#define MYABS( a ) ((a) < 0 ? -(a) : (a) )
#ifdef __FPI__
volatile int sig_count = 0;
double a = 1.0;
double b = 3.0;
double q;
void my_handler( int sig, int fpe ) {
if( sig == SIGFPE ) {
if( fpe == _FPE_INEXACT ) {
sig_count++;
}
} else {
abort();
}
signal( SIGFPE, (__sig_func)my_handler );
}
//#else
volatile int my_matherrno;
int matherr( struct _exception *err )
{
if( strcmp( err->name, "sqrt" ) == 0 ) {
if( err->type == DOMAIN ) {
my_matherrno = DOMAIN;
err->retval = sqrt( -(err->arg1) );
return( 1 );
} else {
return( 0 );
}
}
return( 0 );
}
#endif
void test_complex_math( void )
{
struct complex c = { 5.0, -12.0 };
printf( "Testing complex functions...\n" );
VERIFY( CompDbl( cabs( c ), 13.0 ) );
}
void test_trig( void )
{
printf( "Testing trigonometric functions...\n" );
VERIFY( CompDbl( sin( PI ), 0.0 ) );
VERIFY( CompDbl( sin( 0.0 ), 0.0 ) );
VERIFY( CompDbl( sin( -PI ), 0.0 ) );
VERIFY( CompDbl( sin( PI / 2 ), 1.0 ) );
VERIFY( CompDbl( sin(- PI / 2 ), -1.0 ) );
VERIFY( CompDbl( cos( PI ), -1.0 ) );
VERIFY( CompDbl( cos( 0.0 ), 1.0 ) );
VERIFY( CompDbl( cos( -PI ), -1.0 ) );
VERIFY( CompDbl( cos( PI / 2 ), 0.0 ) );
VERIFY( CompDbl( cos(- PI / 2 ), 0.0 ) );
VERIFY( CompDbl( tan( PI ), 0.0 ) );
VERIFY( CompDbl( tan( 0.0 ), 0.0 ) );
VERIFY( CompDbl( tan( -PI ), 0.0 ) );
VERIFY( CompDbl( tan( PI / 4 ), 1.0 ) );
VERIFY( CompDbl( asin( 1.0 ), PI / 2 ) );
VERIFY( CompDbl( asin( 0.0 ), 0.0 ) );
VERIFY( CompDbl( asin( -1.0 ), -PI / 2 ) );
VERIFY( CompDbl( acos( 1.0 ), 0.0 ) );
VERIFY( CompDbl( acos( 0.0 ), PI / 2 ) );
VERIFY( CompDbl( acos( -1.0 ), PI ) );
VERIFY( CompDbl( atan( 1.0 ), PI / 4 ) );
VERIFY( CompDbl( atan( 0.0 ), 0.0 ) );
VERIFY( CompDbl( atan( -1.0 ), -PI / 4 ) );
VERIFY( CompDbl( atan( DBL_MAX ), PI / 2 ) );
VERIFY( CompDbl( atan( -DBL_MAX ), -PI / 2 ) );
VERIFY( CompDbl( atan2( 2.0, 2.0 ), PI / 4 ) );
VERIFY( CompDbl( atan2( 1.0, -1.0 ), 3 * PI / 4 ) );
VERIFY( CompDbl( atan2( -1.0, -1.0 ), -3 * PI / 4 ) );
VERIFY( CompDbl( atan2( -3.0, 3.0 ), -PI / 4 ) );
VERIFY( CompDbl( atan2( 0.0, 1.0 ), 0.0 ) );
VERIFY( CompDbl( atan2( 1.0, 0.0 ), PI / 2 ) );
VERIFY( CompDbl( atan2( -DBL_MAX, 1.0 ), -PI / 2 ) );
VERIFY( CompDbl( atan2( DBL_MAX, 1.0 ), PI / 2 ) );
VERIFY( CompDbl( atan2( 1.0, DBL_MAX ), 0.0 ) );
VERIFY( CompDbl( atan2( -1.0, DBL_MAX ), 0.0 ) );
VERIFY( CompDbl( hypot( 3.0, 4.0 ), 5.0 ) );
VERIFY( CompDbl( sinh( 1.0 ), 1.1752011936 ) );
VERIFY( CompDbl( sinh( 0.0 ), 0.0 ) );
VERIFY( CompDbl( cosh( 1.0 ), 1.5430806348 ) );
VERIFY( CompDbl( cosh( 0.0 ), 1.0 ) );
VERIFY( CompDbl( tanh( 1.0 ), 0.7615941560 ) );
VERIFY( CompDbl( tanh( 0.0 ), 0.0 ) );
VERIFY( CompDbl( asinh( 1.1752011936 ), 1.0 ) );
VERIFY( CompDbl( asinh( 0.0 ), 0.0 ) );
VERIFY( CompDbl( acosh( 1.5430806348 ), 1.0 ) );
VERIFY( CompDbl( acosh( 1.0 ), 0.0 ) );
VERIFY( CompDbl( atanh( 0.7615941560 ), 1.0 ) );
VERIFY( CompDbl( atanh( 0.0 ), 0.0 ) );
/*
Note:
sinh(1) = 1.175201193643802
sinh(0) = 0.000000000000000
cosh(1) = 1.543080634815244
cosh(0) = 1.000000000000000
tanh(1) = 0.761594155955765
tanh(0) = 0.000000000000000
*/
}
void test_fp_and_80x87_math( void )
{
double dnum;
int inum;
#ifdef __FPI__
unsigned fp_status, fp_control, fp_mask, origbits, bits;
#endif
printf( "Testing other floating point " );
#ifdef __FPI__
printf( "and 80x87 specific " );
#endif
printf( "functions...\n" );
VERIFY( CompDbl( j0( 2.387 ), 0.009288 ) );
VERIFY( CompDbl( j1( 2.387 ), 0.522941 ) );
VERIFY( CompDbl( jn( 2, 2.387 ), 0.428870 ) );
VERIFY( CompDbl( y0( 2.387 ), 0.511681 ) );
VERIFY( CompDbl( y1( 2.387 ), 0.094374 ) );
VERIFY( CompDbl( yn( 2, 2.387 ), -0.432608 ) );
VERIFY( ceil( 1.0001 ) == 2.0 );
VERIFY( ceil( -1.0001 ) == -1.0 );
VERIFY( floor( 1.0001 ) == 1.0 );
VERIFY( floor( -1.0001 ) == -2.0 );
VERIFY( CompDbl( exp( 1.0 ), E ) );
VERIFY( CompDbl( exp( 3.0 ), E * E * E ) );
VERIFY( exp( 0.0 ) == 1.0 );
VERIFY( fabs( -1.5 ) == 1.5 );
VERIFY( fabs( 2.5 ) == 2.5 );
VERIFY( fabs( 0.0 ) == 0.0 );
VERIFY( fmod( 2.5, 0.5 ) == 0.0 );
VERIFY( fmod( 4.5, 2.0 ) == 0.5 );
VERIFY( fmod( -4.5, 2.0 ) == -0.5 );
VERIFY( fmod( -7.5, -2.0 ) == -1.5 );
dnum = frexp( 65535.0, &inum );
VERIFY( inum == 16 );
VERIFY( CompDbl( ldexp( dnum, inum ), 65535.0 ) );
while( inum-- > 0 ) dnum *= 2;
VERIFY( CompDbl( dnum, 65535.0 ) );
VERIFY( CompDbl( log( E ), 1.0 ) );
VERIFY( CompDbl( log( 1.0 ), 0.0 ) );
VERIFY( CompDbl( log( 1.0 / E ), -1.0 ) );
VERIFY( CompDbl( log10( 10.0 ), 1.0 ) );
VERIFY( CompDbl( log10( 1 ), 0.0 ) );
VERIFY( CompDbl( log10( 0.1 ), -1.0 ) );
VERIFY( CompDbl( log2( 65536.0 ), 16.0 ) );
VERIFY( CompDbl( log2( 1 ), 0.0 ) );
VERIFY( CompDbl( log2( 0.25 ), -2.0 ) );
VERIFY( CompDbl( sqrt( 99980001.0 ), 9999.0 ) );
dnum = 1.0/DBL_MIN;
VERIFY( CompDbl( 1.0 / dnum, DBL_MIN ) );
VERIFY( CompDbl( modf( PI, &dnum ), PI - 3.0 ) );
VERIFY( dnum == 3.0 );
VERIFY( CompDbl( modf( -PI, &dnum ) , - PI + 3.0 ) );
VERIFY( dnum == -3.0 );
VERIFY( pow( 1.0, 123456789.0 ) == 1.0 );
VERIFY( pow( 2.0, 16.0 ) == 65536.0 );
VERIFY( CompDbl( pow( E, log(1234.0) ), 1234.0 ) );
#ifdef __FPI__
VERIFY( sqrt( -1 ) == 1 );
// Now my_matherrno should == DOMAIN after calling sqrt( -1 )
// If not, matherr() fails
VERIFY( my_matherrno == DOMAIN );
my_matherrno = 0; // reset
VERIFY( sqrt( 0 ) == 0 );
VERIFY( my_matherrno == 0 );
_fpreset();
fp_status = _clear87();
VERIFY( fp_status == 0 );
//
fp_status = _status87();
VERIFY( fp_status == 0 );
//
_fpreset();
fp_control = _control87( 0, 0 );
bits = fp_control & MCW_IC;
bits = (bits == IC_AFFINE) ? IC_PROJECTIVE : IC_AFFINE;
fp_control = _control87( bits, MCW_IC );
VERIFY( (fp_control & MCW_IC) == bits );
bits = (bits == IC_AFFINE) ? IC_PROJECTIVE : IC_AFFINE;
fp_control = _control87( bits, MCW_IC );
VERIFY( (fp_control & MCW_IC) == bits );
//
fp_control = _control87( 0, 0 );
origbits = fp_control & MCW_RC;
bits = (origbits == RC_NEAR) ? RC_CHOP : RC_NEAR;
fp_control = _control87( bits, MCW_RC );
VERIFY( (fp_control & MCW_RC) == bits );
fp_control = _control87( origbits, MCW_RC );
VERIFY( (fp_control & MCW_RC) == origbits );
//
_fpreset();
fp_control = 0;
fp_mask = EM_PRECISION;
signal( SIGFPE, (__sig_func)my_handler );
(void)_control87( fp_control, fp_mask );
q = a / b;
VERIFY( sig_count > 0 );
fp_control = EM_PRECISION;
(void)_control87( fp_control, fp_mask );
sig_count = 0;
q = a / b;
VERIFY( sig_count == 0 );
signal( SIGFPE, SIG_DFL );
#endif
}
void test_fp_classification( void )
{
#if __STDC_VERSION__ >= 199901L && !defined( __WINDOWS__ )
printf( "Testing C99 floating-point classification functions...\n" );
VERIFY( fpclassify( 0.0 ) == FP_ZERO );
VERIFY( fpclassify( 0.0f ) == FP_ZERO );
VERIFY( fpclassify( 0.0L ) == FP_ZERO );
VERIFY( fpclassify( INFINITY ) == FP_INFINITE );
VERIFY( fpclassify( -INFINITY ) == FP_INFINITE );
VERIFY( fpclassify( NAN ) == FP_NAN );
VERIFY( fpclassify( 1.0f ) == FP_NORMAL );
VERIFY( fpclassify( 0.3L ) == FP_NORMAL );
VERIFY( fpclassify( 423.e34 ) == FP_NORMAL );
VERIFY( isfinite( 0.0 ) );
VERIFY( isfinite( 1.23f ) );
VERIFY( isfinite( 4.56L ) );
VERIFY( !isfinite( NAN ) );
VERIFY( !isfinite( INFINITY ) );
VERIFY( !isinf( NAN ) );
VERIFY( isinf( INFINITY ) );
VERIFY( !isinf( 0.0L ) );
VERIFY( !isinf( 3.0 ) );
VERIFY( isnan( NAN ) );
VERIFY( !isnan( INFINITY ) );
VERIFY( !isnan( 0.0 ) );
VERIFY( !isnan( 3.0f ) );
VERIFY( !isnormal( NAN ) );
VERIFY( !isnormal( INFINITY ) );
VERIFY( !isnormal( 0.0 ) );
VERIFY( isnormal( .4 ) );
VERIFY( isnormal( 3.0f ) );
VERIFY( signbit( -1.0 ) );
VERIFY( !signbit( 1.0L ) );
VERIFY( !signbit( NAN ) );
VERIFY( signbit( -INFINITY ) );
#endif
}
int CompDbl( double n1, double n2 )
{
double num;
if( MYABS( n1 ) < 0.000001 && MYABS( n2 ) < 0.000001 ) return( TRUE );
if( n1 == 0.0 || n2 == 0.0 ) {
return( FALSE );
} else {
num = ( n1 - n2 ) / ( n1 < n2 ? n1 : n2 );
if( MYABS( num ) > 0.0001 ) return( FALSE );
}
return( TRUE );
}
void main( void )
{
test_complex_math();
test_trig();
test_fp_classification();
test_fp_and_80x87_math();
printf( "Tests completed.\n" );
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?