⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 float3.c

📁 美国tern公司开发的嵌入式开发平台586E
💻 C
字号:
/*		 10-13-2000
//	Sample application to demonstrate the use of the Borland/Turbo C++
//	floating point arithmetic in an embedded application.  The key functions
//	defined in this module are matherr(), the user-customizable exception
//	handler  for math run-time library errors, and MyFPHandler(), which
//	handles intrinsic floating point exceptions.
*/

#include	<signal.h>						/* signal(), raise() prototypes */
#include	<setjmp.h>						/* setjmp(), longjmp() prototypes */
#include	<math.h>							/* Trig, exponential function prototypes */
#include	<float.h>						/* Low-level floating point definitions */
#include	<string.h>						/* Prototypes used in matherr() */
#include "586.h"

#define	ERR_LIMIT	0.000001			/* Error delta for examples */
jmp_buf	jbuf ;							/* Exception position data */
float	f1, f2 ;
double d1, d2 ;
unsigned	errors ;
void ftest(void);
unsigned char ledd;
int i;

void main(void)
{
sc_init();
ledd=0;
while(1)
	{
	led(ledd);
	for(i=0;i<50;i++)
	{
	ftest();
	}
	ledd=~ledd;
	}
}

void ftest(void)
{
		/* Initialize the error count and set the default handler */
//		errors = 0 ;
//		signal(SIGFPE, SIG_DFL) ;

for(i=0;i<1000;i++)
{
/* Check that sin(x)^2 + cos(x)^2 = 1 where x is PI/2 */
		f1 = M_PI_2 ;
		f2 = pow(sin(f1), 2.0) + pow(cos(f1), 2.0) ;
		if (fabs(f2 - 1.0) > ERR_LIMIT)
			errors++ ;
/* Check that ln(e^2) = 2 */
		d1 = M_E ;
		d2 = log(pow(d1, 2.0)) ;
		if (fabs(d2 - 2.0) > ERR_LIMIT)
			errors++ ;

		/* Force an error and see that matherr() catches and fixes it */
		d1 = 4.999;
//		d1 = -4.0 ;
		d2 = sqrt(d1) ;
}
		/* Install a new floating point exception handler */
//		signal(SIGFPE, MyFPHandler) ;
		/* Force an intrinsic error and verify it is intercepted */
//		if (setjmp(jbuf) == 0)
//			raise(SIGFPE) ;
//		else
//			errors++ ;							/* This code should also execute */
//		/* Force an intrinsic error and verify it is intercepted */
//		if (setjmp(jbuf) == 0)   {
//			d1 = 0.1 ;
//			d1 = 0.0 ;
//			d2 = 1.0 ;
//			d2 = d2 / d1 ;
//		}
//		else   {
//			d2 = M_PI ;							/* This code should also execute */
//			errors++ ;
//		}
		/* Verify that the correct number of errors were detected */
//		f1 = (errors != 2) ? -1.0 : 1.0 ;
}


/*
//		Function:	MyFPHandler
//
//		This function gains control of floating point exceptions caused by
//		intrinsic floating point operations.
*/

void		MyFPHandler(
				int		sig,				/* SIGFPE */
				int		type				/* Floating point subtype */
			)
{
	/* Reset the math coprocessor */
	_fpreset() ;

	/* Restore the intercept for this signal */
	signal(sig, MyFPHandler) ;
	longjmp(jbuf, type) ;
}


/*
//		Function:	matherr()
//
//		When exceptions are detected in the math library then a call is made
//		to _matherr() with all the available information.  _matherr() does very
//		little, except to map the exception "why" into either ERANGE or EDOMAIN
//		in errno.  Its main purpose is to act as a focal point for changes in
//		error handling.
//
//		The default version of the Borland/Turbo C++ matherr() routine masks
//		underflow and precision errors; others errors are considered
//		fatal.  The rationale for masking underflow and precision errors
//		is that these are not errors according to the ANSI C spec. Consequently,
//		you will get
//		    exp(-1000) = 0
//		    sin(1e100) = NAN
//		without any error or warning, even though there is a total
//		loss of precision in both cases. You can trap these errors
//		by modifying matherr().
//
//		The possible errors are DOMAIN, SING, OVERFLOW, UNDERFLOW, TLOSS,
//		PLOSS and are listed in <math.h>.  As explained above, UNDERFLOW and
//		TLOSS are masked by the default matherr().  PLOSS is not
//		supported by Borland/Turbo C++ and is not generated by any library
//		functions.  The remaining errors, DOMAIN, SING, and OVERFLOW, are
//		fatal with the default matherr().
//
//		You can modify matherr() to be a custom error handling routine (such
//		as one that catches and resolves certain type of errors); the modified
//		matherr() should return 0 if it failed to resolve the error, or non-zero
//		if the error was resolved.  When matherr() returns non-zero, no error
//		message is printed, and errno is not changed.
//
//		The default return value for matherr() is simply 0.  matherr() can
//		also modify e->retval, which propagates through _matherr() back to
//		the original caller.  When matherr() returns 0, (indicating that it
//		was not able to resolve the error) _matherr() sets errno and prints
//		an error message.  When matherr() returns non-zero, (indicating that
//		it was able to resolve the error), errno is not set and no output is
//		generated messages are printed.
//
//		The important thing is that we don't know what error handling you want,
/		but you are assured that all errors will arrive at matherr() with all
//		the information you need to design a custom exception handler.
*/

int	matherr(
			struct	exception	*e		/* Exception structure */
		)
{
	switch (e->type)   {
		case DOMAIN:
			/* Handle the square root of a negative number */
			if (stricmp(e->name, "sqrt") == 0)   {
				e->retval = sqrt(fabs(e->arg1)) ;
				return	1 ;
			}
			break ;

		case UNDERFLOW:
			/* Flush underflow to 0 */
			e->retval = 0 ;
			return	1 ;
	}

	/* Return the code showing the exception hasn't been handled */
	return	0 ;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -