| 1964 | |
| 1965 | |
| 1966 | dsc* evlStdMath(thread_db* tdbb, const SysFunction* function, const NestValueArray& args, |
| 1967 | impure_value* impure) |
| 1968 | { |
| 1969 | fb_assert(args.getCount() == 1); |
| 1970 | fb_assert(function->misc != NULL); |
| 1971 | |
| 1972 | Request* request = tdbb->getRequest(); |
| 1973 | |
| 1974 | const dsc* value = EVL_expr(tdbb, request, args[0]); |
| 1975 | if (request->req_flags & req_null) // return NULL if value is NULL |
| 1976 | return NULL; |
| 1977 | |
| 1978 | const double v = MOV_get_double(tdbb, value); |
| 1979 | double rc; |
| 1980 | |
| 1981 | // CVC: Apparently, gcc has built-in inverse hyperbolic functions, but since |
| 1982 | // VC doesn't, I'm taking the definitions from Wikipedia |
| 1983 | |
| 1984 | switch ((TrigonFunction)(IPTR) function->misc) |
| 1985 | { |
| 1986 | case trfSin: |
| 1987 | rc = sin(v); |
| 1988 | break; |
| 1989 | case trfCos: |
| 1990 | rc = cos(v); |
| 1991 | break; |
| 1992 | case trfTan: |
| 1993 | rc = tan(v); |
| 1994 | break; |
| 1995 | case trfCot: |
| 1996 | if (!v) |
| 1997 | { |
| 1998 | status_exception::raise(Arg::Gds(isc_expression_eval_err) << |
| 1999 | Arg::Gds(isc_sysf_argmustbe_nonzero) << Arg::Str(function->name)); |
| 2000 | } |
| 2001 | rc = fbcot(v); |
| 2002 | break; |
| 2003 | case trfAsin: |
| 2004 | if (v < -1 || v > 1) |
| 2005 | { |
| 2006 | status_exception::raise(Arg::Gds(isc_expression_eval_err) << |
| 2007 | Arg::Gds(isc_sysf_argmustbe_range_inc1_1) << Arg::Str(function->name)); |
| 2008 | } |
| 2009 | rc = asin(v); |
| 2010 | break; |
| 2011 | case trfAcos: |
| 2012 | if (v < -1 || v > 1) |
| 2013 | { |
| 2014 | status_exception::raise(Arg::Gds(isc_expression_eval_err) << |
| 2015 | Arg::Gds(isc_sysf_argmustbe_range_inc1_1) << Arg::Str(function->name)); |
| 2016 | } |
| 2017 | rc = acos(v); |
| 2018 | break; |
| 2019 | case trfAtan: |
| 2020 | rc = atan(v); |
| 2021 | break; |
| 2022 | case trfSinh: |
| 2023 | rc = sinh(v); |
nothing calls this directly
no test coverage detected