I am porting a mathematics application from Borland C++ to Visual C++ 2005 Express Edition beta, but it seems that _matherr does not work as described in msdn. After some research and tries I have succedded in getting _matherr called with the _DOMAIN error (for instance when evaluating log(-1)); but it seems that _PLOSS and _TLOSS are not used and the supporting routines do not complain if things like sin(1e300) are evaluated.
Any ideas to make _matherr work as in Unix or in Borland C++
Thank you

_TLOSS in _matherr
sepehr.Beigi
I have to ask you for more specific list of concerns. Is there a specific code scenario when VC _matherr is different from Borland's one
Thanks,
Nikola
VC++
ginganinja
In this sample the 1.0e300 is a valid double value (<DBL_MAX) and sin() is computed, exception is not thrown. My guess, that Borland folks assume that sin of such a big value is equal to sin(infinite) which is undefined. I guess if VC compiler was letting us enter 1e309 > DLB_MAX, then perhaps in this case CRT could throw TLOSS exception. But this literal is tranlated to a variable of double type and compiler checks for valid range. I do not think something should be change in VC CRT for this case. What kind of issues does this difference in CRTs create in your application
Thanks,
Nikola
cjarvis
Thanks for reporting the issue!
Ayman Shoukry
VC++
GerryT
Thanks,
Ayman.
Sunil S
Unforentally I never tried these fuctions so they may now work easly.
If you cant get the gcc compiler to work you can find help in its usage all over the place. Most open source communities can help you.
I never used the borland compiler so I cant help you with that.
I hope that I was of some assistance.
Rich_Cov
If I compile the code fpe.cpp with Visual C++ I get
_matherr (Domain): log(-2)
log(-2.0) = -1.#IND00e+000
_matherr (Domain): sqrt(-1)
sqrt(-1.0) = -1.#IND00e+000
sin(1.0e300) = 9.804836e-001
but with Borland C++ I get the more sensible
_matherr (Domain): log(-2)
log(-2.0) = -NAN
_matherr (Domain): sqrt(-1)
sqrt(-1.0) = +NAN
_matherr (Total loss of significance): sin(1e+300)
sin(1.0e300) = +NAN
---------------------------------------------------------------------------
-------------------------------------- fpe.cpp ---------------------------
#ifdef __BORLANDC__
#include <windows.h>
#include <stdio.h>
#else
#include
"stdafx.h"#include
<fpieee.h>#endif
#include
<math.h>#include
<excpt.h>#include
<float.h>char
*errs[] = { "Domain", "Singularity", "Overflow","Partial loss of significance", "Total loss of significance",
"Underflow" };
#ifdef
__BORLANDC__#define _EXC_MASK EM_UNDERFLOW + EM_OVERFLOW + EM_ZERODIVIDE + EM_INEXACT
#define TEST(st,op) { _controlfp(_EXC_MASK, MCW_EM); \
__try { \
printf( st " = %e\n\n", op); \
} \
__except (0) {\
printf("Exception raised: \n");\
}}
#else
#define
_EXC_MASK _EM_UNDERFLOW + _EM_OVERFLOW + _EM_ZERODIVIDE + _EM_INEXACT#define
TEST(st,op) { _controlfp(_EXC_MASK, _MCW_EM); \ __try { \printf( st " = %e\n\n", op); \
} \
__except (_fpieee_flt(GetExceptionCode(),GetExceptionInformation(),fpieee_handler)) {\printf("Exception raised: \n");\
}}
#endif
int
_matherr( struct _exception *e ){
printf("_matherr (%s): %s(%lg)\n",errs[e->type-1],e->name,e->arg1);
return 1;}
#ifndef
__BORLANDC__int
fpieee_handler( _FPIEEE_RECORD *pieee ){
return EXCEPTION_CONTINUE_EXECUTION;}
#endif
int
main(int argc, char* argv[]){
TEST("log(-2.0)",log(-2.0));
TEST("sqrt(-1.0)",sqrt(-1.0));
TEST("sin(1.0e300)",sin(1.0e300));
return 0;}
Shlomi Meoded
-0.9857504251603769966...
as can be checked by means of any program with variable precision. Not even the sign is right in VC result!BC does not assume sin(1.0e300) is undefined, it only warns you that it cannot be computed with double precision. I think this is the only reasonable answer, because to compute sin(1.0e300) you have to use a lot of decimal places to reduce the argument to the right interval: maybe [0,2 pi].
Rohit Tela
Nikola
VC++