1919#include < foundation-system.h>
2020
2121#include < float.h>
22+ #include < fenv.h>
2223#include < errno.h>
2324
2425// Older versions of MSVC don't supply "trunc"
@@ -32,15 +33,32 @@ MCTypeInfoRef kMCMathDomainErrorTypeInfo;
3233
3334// //////////////////////////////////////////////////////////////
3435
36+ static inline bool
37+ __MCMathPropagateNanUnary (double p_in, double p_out)
38+ {
39+ if (isnan (p_out) && !isnan (p_in))
40+ return false ;
41+ return true ;
42+ }
43+
44+ static inline bool
45+ __MCMathPropagateNanBinary (double p_left, double p_right, double p_out)
46+ {
47+ if (isnan (p_out) && (!(isnan (p_left) || isnan (p_right))))
48+ return false ;
49+ return true ;
50+ }
51+
52+ // //////////////////////////////////////////////////////////////
53+
3554extern " C" MC_DLLEXPORT void MCMathEvalRealToPowerOfReal (double p_left, double p_right, double & r_output)
3655{
37- errno = 0 ;
3856 r_output = pow (p_left, p_right);
3957
40- if (errno == EDOM )
41- {
42- MCErrorCreateAndThrow ( kMCMathDomainErrorTypeInfo , nil);
43- }
58+ if (__MCMathPropagateNanBinary (p_left, p_right, r_output) )
59+ return ;
60+
61+ MCErrorCreateAndThrow ( kMCMathDomainErrorTypeInfo , nil);
4462}
4563
4664extern " C" MC_DLLEXPORT void MCMathEvalNumberToPowerOfNumber (MCNumberRef p_left, MCNumberRef p_right, MCNumberRef& r_output)
@@ -58,13 +76,12 @@ extern "C" MC_DLLEXPORT void MCMathEvalNumberToPowerOfNumber(MCNumberRef p_left,
5876
5977extern " C" MC_DLLEXPORT void MCMathEvalBase10LogReal (double p_operand, double & r_output)
6078{
61- errno = 0 ;
6279 r_output = log10 (p_operand);
6380
64- if (errno == EDOM )
65- {
66- MCErrorCreateAndThrow ( kMCMathDomainErrorTypeInfo , nil);
67- }
81+ if (__MCMathPropagateNanUnary (p_operand, r_output) )
82+ return ;
83+
84+ MCErrorCreateAndThrow ( kMCMathDomainErrorTypeInfo , nil);
6885}
6986
7087extern " C" MC_DLLEXPORT void MCMathEvalBase10LogNumber (MCNumberRef p_operand, MCNumberRef& r_output)
@@ -81,13 +98,12 @@ extern "C" MC_DLLEXPORT void MCMathEvalBase10LogNumber(MCNumberRef p_operand, MC
8198
8299extern " C" MC_DLLEXPORT void MCMathEvalNaturalLogReal (double p_operand, double & r_output)
83100{
84- errno = 0 ;
85101 r_output = log (p_operand);
86102
87- if (errno == EDOM )
88- {
89- MCErrorCreateAndThrow ( kMCMathDomainErrorTypeInfo , nil);
90- }
103+ if (__MCMathPropagateNanUnary (p_operand, r_output) )
104+ return ;
105+
106+ MCErrorCreateAndThrow ( kMCMathDomainErrorTypeInfo , nil);
91107}
92108
93109extern " C" MC_DLLEXPORT void MCMathEvalNaturalLogNumber (MCNumberRef p_operand, MCNumberRef& r_output)
@@ -172,13 +188,12 @@ extern "C" MC_DLLEXPORT void MCMathEvalTanNumber(MCNumberRef p_operand, MCNumber
172188
173189extern " C" MC_DLLEXPORT void MCMathEvalAsinReal (double p_operand, double & r_output)
174190{
175- errno = 0 ;
176191 r_output = asin (p_operand);
177192
178- if (errno == EDOM )
179- {
180- MCErrorCreateAndThrow ( kMCMathDomainErrorTypeInfo , nil);
181- }
193+ if (__MCMathPropagateNanUnary (p_operand, r_output) )
194+ return ;
195+
196+ MCErrorCreateAndThrow ( kMCMathDomainErrorTypeInfo , nil);
182197}
183198
184199extern " C" MC_DLLEXPORT void MCMathEvalAsinNumber (MCNumberRef p_operand, MCNumberRef& r_output)
@@ -195,13 +210,12 @@ extern "C" MC_DLLEXPORT void MCMathEvalAsinNumber(MCNumberRef p_operand, MCNumbe
195210
196211extern " C" MC_DLLEXPORT void MCMathEvalAcosReal (double p_operand, double & r_output)
197212{
198- errno = 0 ;
199213 r_output = acos (p_operand);
200214
201- if (errno == EDOM )
202- {
203- MCErrorCreateAndThrow ( kMCMathDomainErrorTypeInfo , nil);
204- }
215+ if (__MCMathPropagateNanUnary (p_operand, r_output) )
216+ return ;
217+
218+ MCErrorCreateAndThrow ( kMCMathDomainErrorTypeInfo , nil);
205219}
206220
207221extern " C" MC_DLLEXPORT void MCMathEvalAcosNumber (MCNumberRef p_operand, MCNumberRef& r_output)
0 commit comments