xref: /vim-8.2.3635/src/float.c (revision 2950065e)
101c798c3SYegappan Lakshmanan /* vi:set ts=8 sts=4 sw=4 noet:
201c798c3SYegappan Lakshmanan  *
301c798c3SYegappan Lakshmanan  * VIM - Vi IMproved	by Bram Moolenaar
401c798c3SYegappan Lakshmanan  *
501c798c3SYegappan Lakshmanan  * Do ":help uganda"  in Vim to read copying and usage conditions.
601c798c3SYegappan Lakshmanan  * Do ":help credits" in Vim to see a list of people who contributed.
701c798c3SYegappan Lakshmanan  * See README.txt for an overview of the Vim source code.
801c798c3SYegappan Lakshmanan  */
901c798c3SYegappan Lakshmanan 
1001c798c3SYegappan Lakshmanan /*
1101c798c3SYegappan Lakshmanan  * float.c: Floating point functions
1201c798c3SYegappan Lakshmanan  */
1301c798c3SYegappan Lakshmanan #define USING_FLOAT_STUFF
1401c798c3SYegappan Lakshmanan 
1501c798c3SYegappan Lakshmanan #include "vim.h"
1601c798c3SYegappan Lakshmanan 
1701c798c3SYegappan Lakshmanan #if (defined(FEAT_EVAL) && defined(FEAT_FLOAT)) || defined(PROTO)
1801c798c3SYegappan Lakshmanan 
1901c798c3SYegappan Lakshmanan #ifdef VMS
2001c798c3SYegappan Lakshmanan # include <float.h>
2101c798c3SYegappan Lakshmanan #endif
2201c798c3SYegappan Lakshmanan 
2301c798c3SYegappan Lakshmanan /*
2401c798c3SYegappan Lakshmanan  * Convert the string "text" to a floating point number.
2501c798c3SYegappan Lakshmanan  * This uses strtod().  setlocale(LC_NUMERIC, "C") has been used to make sure
2601c798c3SYegappan Lakshmanan  * this always uses a decimal point.
2701c798c3SYegappan Lakshmanan  * Returns the length of the text that was consumed.
2801c798c3SYegappan Lakshmanan  */
2901c798c3SYegappan Lakshmanan     int
string2float(char_u * text,float_T * value,int skip_quotes)3001c798c3SYegappan Lakshmanan string2float(
3101c798c3SYegappan Lakshmanan     char_u	*text,
32*2950065eSBram Moolenaar     float_T	*value,	    // result stored here
33*2950065eSBram Moolenaar     int		skip_quotes)
3401c798c3SYegappan Lakshmanan {
3501c798c3SYegappan Lakshmanan     char	*s = (char *)text;
3601c798c3SYegappan Lakshmanan     float_T	f;
3701c798c3SYegappan Lakshmanan 
3801c798c3SYegappan Lakshmanan     // MS-Windows does not deal with "inf" and "nan" properly.
3901c798c3SYegappan Lakshmanan     if (STRNICMP(text, "inf", 3) == 0)
4001c798c3SYegappan Lakshmanan     {
4101c798c3SYegappan Lakshmanan 	*value = INFINITY;
4201c798c3SYegappan Lakshmanan 	return 3;
4301c798c3SYegappan Lakshmanan     }
4401c798c3SYegappan Lakshmanan     if (STRNICMP(text, "-inf", 3) == 0)
4501c798c3SYegappan Lakshmanan     {
4601c798c3SYegappan Lakshmanan 	*value = -INFINITY;
4701c798c3SYegappan Lakshmanan 	return 4;
4801c798c3SYegappan Lakshmanan     }
4901c798c3SYegappan Lakshmanan     if (STRNICMP(text, "nan", 3) == 0)
5001c798c3SYegappan Lakshmanan     {
5101c798c3SYegappan Lakshmanan 	*value = NAN;
5201c798c3SYegappan Lakshmanan 	return 3;
5301c798c3SYegappan Lakshmanan     }
54*2950065eSBram Moolenaar     if (skip_quotes && vim_strchr((char_u *)s, '\'') != NULL)
55*2950065eSBram Moolenaar     {
56*2950065eSBram Moolenaar 	char_u	    buf[100];
57*2950065eSBram Moolenaar 	char_u	    *p = buf;
58*2950065eSBram Moolenaar 	int	    quotes = 0;
59*2950065eSBram Moolenaar 
60*2950065eSBram Moolenaar 	vim_strncpy(buf, (char_u *)s, 99);
61*2950065eSBram Moolenaar 	p = buf;
62*2950065eSBram Moolenaar 	for (;;)
63*2950065eSBram Moolenaar 	{
64*2950065eSBram Moolenaar 	    // remove single quotes between digits, not in the exponent
65*2950065eSBram Moolenaar 	    if (*p == '\'')
66*2950065eSBram Moolenaar 	    {
67*2950065eSBram Moolenaar 		++quotes;
68*2950065eSBram Moolenaar 		mch_memmove(p, p + 1, STRLEN(p));
69*2950065eSBram Moolenaar 	    }
70*2950065eSBram Moolenaar 	    if (!vim_isdigit(*p))
71*2950065eSBram Moolenaar 		break;
72*2950065eSBram Moolenaar 	    p = skipdigits(p);
73*2950065eSBram Moolenaar 	}
74*2950065eSBram Moolenaar 	s = (char *)buf;
75*2950065eSBram Moolenaar 	f = strtod(s, &s);
76*2950065eSBram Moolenaar 	*value = f;
77*2950065eSBram Moolenaar 	return (int)((char_u *)s - buf) + quotes;
78*2950065eSBram Moolenaar     }
79*2950065eSBram Moolenaar 
8001c798c3SYegappan Lakshmanan     f = strtod(s, &s);
8101c798c3SYegappan Lakshmanan     *value = f;
8201c798c3SYegappan Lakshmanan     return (int)((char_u *)s - text);
8301c798c3SYegappan Lakshmanan }
8401c798c3SYegappan Lakshmanan 
8501c798c3SYegappan Lakshmanan /*
8601c798c3SYegappan Lakshmanan  * Get the float value of "argvars[0]" into "f".
8701c798c3SYegappan Lakshmanan  * Returns FAIL when the argument is not a Number or Float.
8801c798c3SYegappan Lakshmanan  */
8901c798c3SYegappan Lakshmanan     static int
get_float_arg(typval_T * argvars,float_T * f)9001c798c3SYegappan Lakshmanan get_float_arg(typval_T *argvars, float_T *f)
9101c798c3SYegappan Lakshmanan {
9201c798c3SYegappan Lakshmanan     if (argvars[0].v_type == VAR_FLOAT)
9301c798c3SYegappan Lakshmanan     {
9401c798c3SYegappan Lakshmanan 	*f = argvars[0].vval.v_float;
9501c798c3SYegappan Lakshmanan 	return OK;
9601c798c3SYegappan Lakshmanan     }
9701c798c3SYegappan Lakshmanan     if (argvars[0].v_type == VAR_NUMBER)
9801c798c3SYegappan Lakshmanan     {
9901c798c3SYegappan Lakshmanan 	*f = (float_T)argvars[0].vval.v_number;
10001c798c3SYegappan Lakshmanan 	return OK;
10101c798c3SYegappan Lakshmanan     }
10201c798c3SYegappan Lakshmanan     emsg(_("E808: Number or Float required"));
10301c798c3SYegappan Lakshmanan     return FAIL;
10401c798c3SYegappan Lakshmanan }
10501c798c3SYegappan Lakshmanan 
10601c798c3SYegappan Lakshmanan /*
10701c798c3SYegappan Lakshmanan  * "abs(expr)" function
10801c798c3SYegappan Lakshmanan  */
10901c798c3SYegappan Lakshmanan     void
f_abs(typval_T * argvars,typval_T * rettv)11001c798c3SYegappan Lakshmanan f_abs(typval_T *argvars, typval_T *rettv)
11101c798c3SYegappan Lakshmanan {
1124490ec4eSYegappan Lakshmanan     if (in_vim9script() && check_for_float_or_nr_arg(argvars, 0) == FAIL)
1134490ec4eSYegappan Lakshmanan 	return;
1144490ec4eSYegappan Lakshmanan 
11501c798c3SYegappan Lakshmanan     if (argvars[0].v_type == VAR_FLOAT)
11601c798c3SYegappan Lakshmanan     {
11701c798c3SYegappan Lakshmanan 	rettv->v_type = VAR_FLOAT;
11801c798c3SYegappan Lakshmanan 	rettv->vval.v_float = fabs(argvars[0].vval.v_float);
11901c798c3SYegappan Lakshmanan     }
12001c798c3SYegappan Lakshmanan     else
12101c798c3SYegappan Lakshmanan     {
12201c798c3SYegappan Lakshmanan 	varnumber_T	n;
12301c798c3SYegappan Lakshmanan 	int		error = FALSE;
12401c798c3SYegappan Lakshmanan 
12501c798c3SYegappan Lakshmanan 	n = tv_get_number_chk(&argvars[0], &error);
12601c798c3SYegappan Lakshmanan 	if (error)
12701c798c3SYegappan Lakshmanan 	    rettv->vval.v_number = -1;
12801c798c3SYegappan Lakshmanan 	else if (n > 0)
12901c798c3SYegappan Lakshmanan 	    rettv->vval.v_number = n;
13001c798c3SYegappan Lakshmanan 	else
13101c798c3SYegappan Lakshmanan 	    rettv->vval.v_number = -n;
13201c798c3SYegappan Lakshmanan     }
13301c798c3SYegappan Lakshmanan }
13401c798c3SYegappan Lakshmanan 
13501c798c3SYegappan Lakshmanan /*
13601c798c3SYegappan Lakshmanan  * "acos()" function
13701c798c3SYegappan Lakshmanan  */
13801c798c3SYegappan Lakshmanan     void
f_acos(typval_T * argvars,typval_T * rettv)13901c798c3SYegappan Lakshmanan f_acos(typval_T *argvars, typval_T *rettv)
14001c798c3SYegappan Lakshmanan {
14101c798c3SYegappan Lakshmanan     float_T	f = 0.0;
14201c798c3SYegappan Lakshmanan 
1434490ec4eSYegappan Lakshmanan     if (in_vim9script() && check_for_float_or_nr_arg(argvars, 0) == FAIL)
1444490ec4eSYegappan Lakshmanan 	return;
1454490ec4eSYegappan Lakshmanan 
14601c798c3SYegappan Lakshmanan     rettv->v_type = VAR_FLOAT;
14701c798c3SYegappan Lakshmanan     if (get_float_arg(argvars, &f) == OK)
14801c798c3SYegappan Lakshmanan 	rettv->vval.v_float = acos(f);
14901c798c3SYegappan Lakshmanan     else
15001c798c3SYegappan Lakshmanan 	rettv->vval.v_float = 0.0;
15101c798c3SYegappan Lakshmanan }
15201c798c3SYegappan Lakshmanan 
15301c798c3SYegappan Lakshmanan /*
15401c798c3SYegappan Lakshmanan  * "asin()" function
15501c798c3SYegappan Lakshmanan  */
15601c798c3SYegappan Lakshmanan     void
f_asin(typval_T * argvars,typval_T * rettv)15701c798c3SYegappan Lakshmanan f_asin(typval_T *argvars, typval_T *rettv)
15801c798c3SYegappan Lakshmanan {
15901c798c3SYegappan Lakshmanan     float_T	f = 0.0;
16001c798c3SYegappan Lakshmanan 
1614490ec4eSYegappan Lakshmanan     if (in_vim9script() && check_for_float_or_nr_arg(argvars, 0) == FAIL)
1624490ec4eSYegappan Lakshmanan 	return;
1634490ec4eSYegappan Lakshmanan 
16401c798c3SYegappan Lakshmanan     rettv->v_type = VAR_FLOAT;
16501c798c3SYegappan Lakshmanan     if (get_float_arg(argvars, &f) == OK)
16601c798c3SYegappan Lakshmanan 	rettv->vval.v_float = asin(f);
16701c798c3SYegappan Lakshmanan     else
16801c798c3SYegappan Lakshmanan 	rettv->vval.v_float = 0.0;
16901c798c3SYegappan Lakshmanan }
17001c798c3SYegappan Lakshmanan 
17101c798c3SYegappan Lakshmanan /*
17201c798c3SYegappan Lakshmanan  * "atan()" function
17301c798c3SYegappan Lakshmanan  */
17401c798c3SYegappan Lakshmanan     void
f_atan(typval_T * argvars,typval_T * rettv)17501c798c3SYegappan Lakshmanan f_atan(typval_T *argvars, typval_T *rettv)
17601c798c3SYegappan Lakshmanan {
17701c798c3SYegappan Lakshmanan     float_T	f = 0.0;
17801c798c3SYegappan Lakshmanan 
1794490ec4eSYegappan Lakshmanan     if (in_vim9script() && check_for_float_or_nr_arg(argvars, 0) == FAIL)
1804490ec4eSYegappan Lakshmanan 	return;
1814490ec4eSYegappan Lakshmanan 
18201c798c3SYegappan Lakshmanan     rettv->v_type = VAR_FLOAT;
18301c798c3SYegappan Lakshmanan     if (get_float_arg(argvars, &f) == OK)
18401c798c3SYegappan Lakshmanan 	rettv->vval.v_float = atan(f);
18501c798c3SYegappan Lakshmanan     else
18601c798c3SYegappan Lakshmanan 	rettv->vval.v_float = 0.0;
18701c798c3SYegappan Lakshmanan }
18801c798c3SYegappan Lakshmanan 
18901c798c3SYegappan Lakshmanan /*
19001c798c3SYegappan Lakshmanan  * "atan2()" function
19101c798c3SYegappan Lakshmanan  */
19201c798c3SYegappan Lakshmanan     void
f_atan2(typval_T * argvars,typval_T * rettv)19301c798c3SYegappan Lakshmanan f_atan2(typval_T *argvars, typval_T *rettv)
19401c798c3SYegappan Lakshmanan {
19501c798c3SYegappan Lakshmanan     float_T	fx = 0.0, fy = 0.0;
19601c798c3SYegappan Lakshmanan 
1974490ec4eSYegappan Lakshmanan     if (in_vim9script()
1984490ec4eSYegappan Lakshmanan 	    && (check_for_float_or_nr_arg(argvars, 0) == FAIL
1994490ec4eSYegappan Lakshmanan 		|| check_for_float_or_nr_arg(argvars, 1) == FAIL))
2004490ec4eSYegappan Lakshmanan 	return;
2014490ec4eSYegappan Lakshmanan 
20201c798c3SYegappan Lakshmanan     rettv->v_type = VAR_FLOAT;
20301c798c3SYegappan Lakshmanan     if (get_float_arg(argvars, &fx) == OK
20401c798c3SYegappan Lakshmanan 				     && get_float_arg(&argvars[1], &fy) == OK)
20501c798c3SYegappan Lakshmanan 	rettv->vval.v_float = atan2(fx, fy);
20601c798c3SYegappan Lakshmanan     else
20701c798c3SYegappan Lakshmanan 	rettv->vval.v_float = 0.0;
20801c798c3SYegappan Lakshmanan }
20901c798c3SYegappan Lakshmanan 
21001c798c3SYegappan Lakshmanan /*
21101c798c3SYegappan Lakshmanan  * "ceil({float})" function
21201c798c3SYegappan Lakshmanan  */
21301c798c3SYegappan Lakshmanan     void
f_ceil(typval_T * argvars,typval_T * rettv)21401c798c3SYegappan Lakshmanan f_ceil(typval_T *argvars, typval_T *rettv)
21501c798c3SYegappan Lakshmanan {
21601c798c3SYegappan Lakshmanan     float_T	f = 0.0;
21701c798c3SYegappan Lakshmanan 
2184490ec4eSYegappan Lakshmanan     if (in_vim9script() && check_for_float_or_nr_arg(argvars, 0) == FAIL)
2194490ec4eSYegappan Lakshmanan 	return;
2204490ec4eSYegappan Lakshmanan 
22101c798c3SYegappan Lakshmanan     rettv->v_type = VAR_FLOAT;
22201c798c3SYegappan Lakshmanan     if (get_float_arg(argvars, &f) == OK)
22301c798c3SYegappan Lakshmanan 	rettv->vval.v_float = ceil(f);
22401c798c3SYegappan Lakshmanan     else
22501c798c3SYegappan Lakshmanan 	rettv->vval.v_float = 0.0;
22601c798c3SYegappan Lakshmanan }
22701c798c3SYegappan Lakshmanan 
22801c798c3SYegappan Lakshmanan /*
22901c798c3SYegappan Lakshmanan  * "cos()" function
23001c798c3SYegappan Lakshmanan  */
23101c798c3SYegappan Lakshmanan     void
f_cos(typval_T * argvars,typval_T * rettv)23201c798c3SYegappan Lakshmanan f_cos(typval_T *argvars, typval_T *rettv)
23301c798c3SYegappan Lakshmanan {
23401c798c3SYegappan Lakshmanan     float_T	f = 0.0;
23501c798c3SYegappan Lakshmanan 
2364490ec4eSYegappan Lakshmanan     if (in_vim9script() && check_for_float_or_nr_arg(argvars, 0) == FAIL)
2374490ec4eSYegappan Lakshmanan 	return;
2384490ec4eSYegappan Lakshmanan 
23901c798c3SYegappan Lakshmanan     rettv->v_type = VAR_FLOAT;
24001c798c3SYegappan Lakshmanan     if (get_float_arg(argvars, &f) == OK)
24101c798c3SYegappan Lakshmanan 	rettv->vval.v_float = cos(f);
24201c798c3SYegappan Lakshmanan     else
24301c798c3SYegappan Lakshmanan 	rettv->vval.v_float = 0.0;
24401c798c3SYegappan Lakshmanan }
24501c798c3SYegappan Lakshmanan 
24601c798c3SYegappan Lakshmanan /*
24701c798c3SYegappan Lakshmanan  * "cosh()" function
24801c798c3SYegappan Lakshmanan  */
24901c798c3SYegappan Lakshmanan     void
f_cosh(typval_T * argvars,typval_T * rettv)25001c798c3SYegappan Lakshmanan f_cosh(typval_T *argvars, typval_T *rettv)
25101c798c3SYegappan Lakshmanan {
25201c798c3SYegappan Lakshmanan     float_T	f = 0.0;
25301c798c3SYegappan Lakshmanan 
2544490ec4eSYegappan Lakshmanan     if (in_vim9script() && check_for_float_or_nr_arg(argvars, 0) == FAIL)
2554490ec4eSYegappan Lakshmanan 	return;
2564490ec4eSYegappan Lakshmanan 
25701c798c3SYegappan Lakshmanan     rettv->v_type = VAR_FLOAT;
25801c798c3SYegappan Lakshmanan     if (get_float_arg(argvars, &f) == OK)
25901c798c3SYegappan Lakshmanan 	rettv->vval.v_float = cosh(f);
26001c798c3SYegappan Lakshmanan     else
26101c798c3SYegappan Lakshmanan 	rettv->vval.v_float = 0.0;
26201c798c3SYegappan Lakshmanan }
26301c798c3SYegappan Lakshmanan 
26401c798c3SYegappan Lakshmanan /*
26501c798c3SYegappan Lakshmanan  * "exp()" function
26601c798c3SYegappan Lakshmanan  */
26701c798c3SYegappan Lakshmanan     void
f_exp(typval_T * argvars,typval_T * rettv)26801c798c3SYegappan Lakshmanan f_exp(typval_T *argvars, typval_T *rettv)
26901c798c3SYegappan Lakshmanan {
27001c798c3SYegappan Lakshmanan     float_T	f = 0.0;
27101c798c3SYegappan Lakshmanan 
2724490ec4eSYegappan Lakshmanan     if (in_vim9script() && check_for_float_or_nr_arg(argvars, 0) == FAIL)
2734490ec4eSYegappan Lakshmanan 	return;
2744490ec4eSYegappan Lakshmanan 
27501c798c3SYegappan Lakshmanan     rettv->v_type = VAR_FLOAT;
27601c798c3SYegappan Lakshmanan     if (get_float_arg(argvars, &f) == OK)
27701c798c3SYegappan Lakshmanan 	rettv->vval.v_float = exp(f);
27801c798c3SYegappan Lakshmanan     else
27901c798c3SYegappan Lakshmanan 	rettv->vval.v_float = 0.0;
28001c798c3SYegappan Lakshmanan }
28101c798c3SYegappan Lakshmanan 
28201c798c3SYegappan Lakshmanan /*
28301c798c3SYegappan Lakshmanan  * "float2nr({float})" function
28401c798c3SYegappan Lakshmanan  */
28501c798c3SYegappan Lakshmanan     void
f_float2nr(typval_T * argvars,typval_T * rettv)28601c798c3SYegappan Lakshmanan f_float2nr(typval_T *argvars, typval_T *rettv)
28701c798c3SYegappan Lakshmanan {
28801c798c3SYegappan Lakshmanan     float_T	f = 0.0;
28901c798c3SYegappan Lakshmanan 
2904490ec4eSYegappan Lakshmanan     if (in_vim9script() && check_for_float_or_nr_arg(argvars, 0) == FAIL)
2914490ec4eSYegappan Lakshmanan 	return;
2924490ec4eSYegappan Lakshmanan 
29301c798c3SYegappan Lakshmanan     if (get_float_arg(argvars, &f) == OK)
29401c798c3SYegappan Lakshmanan     {
29501c798c3SYegappan Lakshmanan 	if (f <= (float_T)-VARNUM_MAX + DBL_EPSILON)
29601c798c3SYegappan Lakshmanan 	    rettv->vval.v_number = -VARNUM_MAX;
29701c798c3SYegappan Lakshmanan 	else if (f >= (float_T)VARNUM_MAX - DBL_EPSILON)
29801c798c3SYegappan Lakshmanan 	    rettv->vval.v_number = VARNUM_MAX;
29901c798c3SYegappan Lakshmanan 	else
30001c798c3SYegappan Lakshmanan 	    rettv->vval.v_number = (varnumber_T)f;
30101c798c3SYegappan Lakshmanan     }
30201c798c3SYegappan Lakshmanan }
30301c798c3SYegappan Lakshmanan 
30401c798c3SYegappan Lakshmanan /*
30501c798c3SYegappan Lakshmanan  * "floor({float})" function
30601c798c3SYegappan Lakshmanan  */
30701c798c3SYegappan Lakshmanan     void
f_floor(typval_T * argvars,typval_T * rettv)30801c798c3SYegappan Lakshmanan f_floor(typval_T *argvars, typval_T *rettv)
30901c798c3SYegappan Lakshmanan {
31001c798c3SYegappan Lakshmanan     float_T	f = 0.0;
31101c798c3SYegappan Lakshmanan 
3124490ec4eSYegappan Lakshmanan     if (in_vim9script() && check_for_float_or_nr_arg(argvars, 0) == FAIL)
3134490ec4eSYegappan Lakshmanan 	return;
3144490ec4eSYegappan Lakshmanan 
31501c798c3SYegappan Lakshmanan     rettv->v_type = VAR_FLOAT;
31601c798c3SYegappan Lakshmanan     if (get_float_arg(argvars, &f) == OK)
31701c798c3SYegappan Lakshmanan 	rettv->vval.v_float = floor(f);
31801c798c3SYegappan Lakshmanan     else
31901c798c3SYegappan Lakshmanan 	rettv->vval.v_float = 0.0;
32001c798c3SYegappan Lakshmanan }
32101c798c3SYegappan Lakshmanan 
32201c798c3SYegappan Lakshmanan /*
32301c798c3SYegappan Lakshmanan  * "fmod()" function
32401c798c3SYegappan Lakshmanan  */
32501c798c3SYegappan Lakshmanan     void
f_fmod(typval_T * argvars,typval_T * rettv)32601c798c3SYegappan Lakshmanan f_fmod(typval_T *argvars, typval_T *rettv)
32701c798c3SYegappan Lakshmanan {
32801c798c3SYegappan Lakshmanan     float_T	fx = 0.0, fy = 0.0;
32901c798c3SYegappan Lakshmanan 
3304490ec4eSYegappan Lakshmanan     if (in_vim9script()
3314490ec4eSYegappan Lakshmanan 	    && (check_for_float_or_nr_arg(argvars, 0) == FAIL
3324490ec4eSYegappan Lakshmanan 		|| check_for_float_or_nr_arg(argvars, 1) == FAIL))
3334490ec4eSYegappan Lakshmanan 	return;
3344490ec4eSYegappan Lakshmanan 
33501c798c3SYegappan Lakshmanan     rettv->v_type = VAR_FLOAT;
33601c798c3SYegappan Lakshmanan     if (get_float_arg(argvars, &fx) == OK
33701c798c3SYegappan Lakshmanan 				     && get_float_arg(&argvars[1], &fy) == OK)
33801c798c3SYegappan Lakshmanan 	rettv->vval.v_float = fmod(fx, fy);
33901c798c3SYegappan Lakshmanan     else
34001c798c3SYegappan Lakshmanan 	rettv->vval.v_float = 0.0;
34101c798c3SYegappan Lakshmanan }
34201c798c3SYegappan Lakshmanan 
34301c798c3SYegappan Lakshmanan # if defined(HAVE_MATH_H) || defined(PROTO)
34401c798c3SYegappan Lakshmanan /*
34501c798c3SYegappan Lakshmanan  * "isinf()" function
34601c798c3SYegappan Lakshmanan  */
34701c798c3SYegappan Lakshmanan     void
f_isinf(typval_T * argvars,typval_T * rettv)34801c798c3SYegappan Lakshmanan f_isinf(typval_T *argvars, typval_T *rettv)
34901c798c3SYegappan Lakshmanan {
3504490ec4eSYegappan Lakshmanan     if (in_vim9script() && check_for_float_or_nr_arg(argvars, 0) == FAIL)
3514490ec4eSYegappan Lakshmanan 	return;
3524490ec4eSYegappan Lakshmanan 
35301c798c3SYegappan Lakshmanan     if (argvars[0].v_type == VAR_FLOAT && isinf(argvars[0].vval.v_float))
35401c798c3SYegappan Lakshmanan 	rettv->vval.v_number = argvars[0].vval.v_float > 0.0 ? 1 : -1;
35501c798c3SYegappan Lakshmanan }
35601c798c3SYegappan Lakshmanan 
35701c798c3SYegappan Lakshmanan /*
35801c798c3SYegappan Lakshmanan  * "isnan()" function
35901c798c3SYegappan Lakshmanan  */
36001c798c3SYegappan Lakshmanan     void
f_isnan(typval_T * argvars,typval_T * rettv)36101c798c3SYegappan Lakshmanan f_isnan(typval_T *argvars, typval_T *rettv)
36201c798c3SYegappan Lakshmanan {
3634490ec4eSYegappan Lakshmanan     if (in_vim9script() && check_for_float_or_nr_arg(argvars, 0) == FAIL)
3644490ec4eSYegappan Lakshmanan 	return;
3654490ec4eSYegappan Lakshmanan 
36601c798c3SYegappan Lakshmanan     rettv->vval.v_number = argvars[0].v_type == VAR_FLOAT
36701c798c3SYegappan Lakshmanan 					    && isnan(argvars[0].vval.v_float);
36801c798c3SYegappan Lakshmanan }
36901c798c3SYegappan Lakshmanan # endif
37001c798c3SYegappan Lakshmanan 
37101c798c3SYegappan Lakshmanan /*
37201c798c3SYegappan Lakshmanan  * "log()" function
37301c798c3SYegappan Lakshmanan  */
37401c798c3SYegappan Lakshmanan     void
f_log(typval_T * argvars,typval_T * rettv)37501c798c3SYegappan Lakshmanan f_log(typval_T *argvars, typval_T *rettv)
37601c798c3SYegappan Lakshmanan {
37701c798c3SYegappan Lakshmanan     float_T	f = 0.0;
37801c798c3SYegappan Lakshmanan 
3794490ec4eSYegappan Lakshmanan     if (in_vim9script() && check_for_float_or_nr_arg(argvars, 0) == FAIL)
3804490ec4eSYegappan Lakshmanan 	return;
3814490ec4eSYegappan Lakshmanan 
38201c798c3SYegappan Lakshmanan     rettv->v_type = VAR_FLOAT;
38301c798c3SYegappan Lakshmanan     if (get_float_arg(argvars, &f) == OK)
38401c798c3SYegappan Lakshmanan 	rettv->vval.v_float = log(f);
38501c798c3SYegappan Lakshmanan     else
38601c798c3SYegappan Lakshmanan 	rettv->vval.v_float = 0.0;
38701c798c3SYegappan Lakshmanan }
38801c798c3SYegappan Lakshmanan 
38901c798c3SYegappan Lakshmanan /*
39001c798c3SYegappan Lakshmanan  * "log10()" function
39101c798c3SYegappan Lakshmanan  */
39201c798c3SYegappan Lakshmanan     void
f_log10(typval_T * argvars,typval_T * rettv)39301c798c3SYegappan Lakshmanan f_log10(typval_T *argvars, typval_T *rettv)
39401c798c3SYegappan Lakshmanan {
39501c798c3SYegappan Lakshmanan     float_T	f = 0.0;
39601c798c3SYegappan Lakshmanan 
3974490ec4eSYegappan Lakshmanan     if (in_vim9script() && check_for_float_or_nr_arg(argvars, 0) == FAIL)
3984490ec4eSYegappan Lakshmanan 	return;
3994490ec4eSYegappan Lakshmanan 
40001c798c3SYegappan Lakshmanan     rettv->v_type = VAR_FLOAT;
40101c798c3SYegappan Lakshmanan     if (get_float_arg(argvars, &f) == OK)
40201c798c3SYegappan Lakshmanan 	rettv->vval.v_float = log10(f);
40301c798c3SYegappan Lakshmanan     else
40401c798c3SYegappan Lakshmanan 	rettv->vval.v_float = 0.0;
40501c798c3SYegappan Lakshmanan }
40601c798c3SYegappan Lakshmanan 
40701c798c3SYegappan Lakshmanan /*
40801c798c3SYegappan Lakshmanan  * "pow()" function
40901c798c3SYegappan Lakshmanan  */
41001c798c3SYegappan Lakshmanan     void
f_pow(typval_T * argvars,typval_T * rettv)41101c798c3SYegappan Lakshmanan f_pow(typval_T *argvars, typval_T *rettv)
41201c798c3SYegappan Lakshmanan {
41301c798c3SYegappan Lakshmanan     float_T	fx = 0.0, fy = 0.0;
41401c798c3SYegappan Lakshmanan 
4154490ec4eSYegappan Lakshmanan     if (in_vim9script()
4164490ec4eSYegappan Lakshmanan 	    && (check_for_float_or_nr_arg(argvars, 0) == FAIL
4174490ec4eSYegappan Lakshmanan 		|| check_for_float_or_nr_arg(argvars, 1) == FAIL))
4184490ec4eSYegappan Lakshmanan 	return;
4194490ec4eSYegappan Lakshmanan 
42001c798c3SYegappan Lakshmanan     rettv->v_type = VAR_FLOAT;
42101c798c3SYegappan Lakshmanan     if (get_float_arg(argvars, &fx) == OK
42201c798c3SYegappan Lakshmanan 				     && get_float_arg(&argvars[1], &fy) == OK)
42301c798c3SYegappan Lakshmanan 	rettv->vval.v_float = pow(fx, fy);
42401c798c3SYegappan Lakshmanan     else
42501c798c3SYegappan Lakshmanan 	rettv->vval.v_float = 0.0;
42601c798c3SYegappan Lakshmanan }
42701c798c3SYegappan Lakshmanan 
42801c798c3SYegappan Lakshmanan 
42901c798c3SYegappan Lakshmanan /*
43001c798c3SYegappan Lakshmanan  * round() is not in C90, use ceil() or floor() instead.
43101c798c3SYegappan Lakshmanan  */
43201c798c3SYegappan Lakshmanan     float_T
vim_round(float_T f)43301c798c3SYegappan Lakshmanan vim_round(float_T f)
43401c798c3SYegappan Lakshmanan {
43501c798c3SYegappan Lakshmanan     return f > 0 ? floor(f + 0.5) : ceil(f - 0.5);
43601c798c3SYegappan Lakshmanan }
43701c798c3SYegappan Lakshmanan 
43801c798c3SYegappan Lakshmanan /*
43901c798c3SYegappan Lakshmanan  * "round({float})" function
44001c798c3SYegappan Lakshmanan  */
44101c798c3SYegappan Lakshmanan     void
f_round(typval_T * argvars,typval_T * rettv)44201c798c3SYegappan Lakshmanan f_round(typval_T *argvars, typval_T *rettv)
44301c798c3SYegappan Lakshmanan {
44401c798c3SYegappan Lakshmanan     float_T	f = 0.0;
44501c798c3SYegappan Lakshmanan 
4464490ec4eSYegappan Lakshmanan     if (in_vim9script() && check_for_float_or_nr_arg(argvars, 0) == FAIL)
4474490ec4eSYegappan Lakshmanan 	return;
4484490ec4eSYegappan Lakshmanan 
44901c798c3SYegappan Lakshmanan     rettv->v_type = VAR_FLOAT;
45001c798c3SYegappan Lakshmanan     if (get_float_arg(argvars, &f) == OK)
45101c798c3SYegappan Lakshmanan 	rettv->vval.v_float = vim_round(f);
45201c798c3SYegappan Lakshmanan     else
45301c798c3SYegappan Lakshmanan 	rettv->vval.v_float = 0.0;
45401c798c3SYegappan Lakshmanan }
45501c798c3SYegappan Lakshmanan 
45601c798c3SYegappan Lakshmanan /*
45701c798c3SYegappan Lakshmanan  * "sin()" function
45801c798c3SYegappan Lakshmanan  */
45901c798c3SYegappan Lakshmanan     void
f_sin(typval_T * argvars,typval_T * rettv)46001c798c3SYegappan Lakshmanan f_sin(typval_T *argvars, typval_T *rettv)
46101c798c3SYegappan Lakshmanan {
46201c798c3SYegappan Lakshmanan     float_T	f = 0.0;
46301c798c3SYegappan Lakshmanan 
4644490ec4eSYegappan Lakshmanan     if (in_vim9script() && check_for_float_or_nr_arg(argvars, 0) == FAIL)
4654490ec4eSYegappan Lakshmanan 	return;
4664490ec4eSYegappan Lakshmanan 
46701c798c3SYegappan Lakshmanan     rettv->v_type = VAR_FLOAT;
46801c798c3SYegappan Lakshmanan     if (get_float_arg(argvars, &f) == OK)
46901c798c3SYegappan Lakshmanan 	rettv->vval.v_float = sin(f);
47001c798c3SYegappan Lakshmanan     else
47101c798c3SYegappan Lakshmanan 	rettv->vval.v_float = 0.0;
47201c798c3SYegappan Lakshmanan }
47301c798c3SYegappan Lakshmanan 
47401c798c3SYegappan Lakshmanan /*
47501c798c3SYegappan Lakshmanan  * "sinh()" function
47601c798c3SYegappan Lakshmanan  */
47701c798c3SYegappan Lakshmanan     void
f_sinh(typval_T * argvars,typval_T * rettv)47801c798c3SYegappan Lakshmanan f_sinh(typval_T *argvars, typval_T *rettv)
47901c798c3SYegappan Lakshmanan {
48001c798c3SYegappan Lakshmanan     float_T	f = 0.0;
48101c798c3SYegappan Lakshmanan 
4824490ec4eSYegappan Lakshmanan     if (in_vim9script() && check_for_float_or_nr_arg(argvars, 0) == FAIL)
4834490ec4eSYegappan Lakshmanan 	return;
4844490ec4eSYegappan Lakshmanan 
48501c798c3SYegappan Lakshmanan     rettv->v_type = VAR_FLOAT;
48601c798c3SYegappan Lakshmanan     if (get_float_arg(argvars, &f) == OK)
48701c798c3SYegappan Lakshmanan 	rettv->vval.v_float = sinh(f);
48801c798c3SYegappan Lakshmanan     else
48901c798c3SYegappan Lakshmanan 	rettv->vval.v_float = 0.0;
49001c798c3SYegappan Lakshmanan }
49101c798c3SYegappan Lakshmanan 
49201c798c3SYegappan Lakshmanan /*
49301c798c3SYegappan Lakshmanan  * "sqrt()" function
49401c798c3SYegappan Lakshmanan  */
49501c798c3SYegappan Lakshmanan     void
f_sqrt(typval_T * argvars,typval_T * rettv)49601c798c3SYegappan Lakshmanan f_sqrt(typval_T *argvars, typval_T *rettv)
49701c798c3SYegappan Lakshmanan {
49801c798c3SYegappan Lakshmanan     float_T	f = 0.0;
49901c798c3SYegappan Lakshmanan 
5004490ec4eSYegappan Lakshmanan     if (in_vim9script() && check_for_float_or_nr_arg(argvars, 0) == FAIL)
5014490ec4eSYegappan Lakshmanan 	return;
5024490ec4eSYegappan Lakshmanan 
50301c798c3SYegappan Lakshmanan     rettv->v_type = VAR_FLOAT;
50401c798c3SYegappan Lakshmanan     if (get_float_arg(argvars, &f) == OK)
50501c798c3SYegappan Lakshmanan 	rettv->vval.v_float = sqrt(f);
50601c798c3SYegappan Lakshmanan     else
50701c798c3SYegappan Lakshmanan 	rettv->vval.v_float = 0.0;
50801c798c3SYegappan Lakshmanan }
50901c798c3SYegappan Lakshmanan 
51001c798c3SYegappan Lakshmanan /*
51101c798c3SYegappan Lakshmanan  * "str2float()" function
51201c798c3SYegappan Lakshmanan  */
51301c798c3SYegappan Lakshmanan     void
f_str2float(typval_T * argvars,typval_T * rettv)51401c798c3SYegappan Lakshmanan f_str2float(typval_T *argvars, typval_T *rettv)
51501c798c3SYegappan Lakshmanan {
5164490ec4eSYegappan Lakshmanan     char_u *p;
5174490ec4eSYegappan Lakshmanan     int     isneg;
518*2950065eSBram Moolenaar     int	    skip_quotes;
5194490ec4eSYegappan Lakshmanan 
5204490ec4eSYegappan Lakshmanan     if (in_vim9script() && check_for_string_arg(argvars, 0) == FAIL)
5214490ec4eSYegappan Lakshmanan 	return;
5224490ec4eSYegappan Lakshmanan 
523*2950065eSBram Moolenaar     skip_quotes = argvars[1].v_type != VAR_UNKNOWN && tv_get_bool(&argvars[1]);
524*2950065eSBram Moolenaar 
5254490ec4eSYegappan Lakshmanan     p = skipwhite(tv_get_string_strict(&argvars[0]));
5264490ec4eSYegappan Lakshmanan     isneg = (*p == '-');
52701c798c3SYegappan Lakshmanan 
52801c798c3SYegappan Lakshmanan     if (*p == '+' || *p == '-')
52901c798c3SYegappan Lakshmanan 	p = skipwhite(p + 1);
530*2950065eSBram Moolenaar     (void)string2float(p, &rettv->vval.v_float, skip_quotes);
53101c798c3SYegappan Lakshmanan     if (isneg)
53201c798c3SYegappan Lakshmanan 	rettv->vval.v_float *= -1;
53301c798c3SYegappan Lakshmanan     rettv->v_type = VAR_FLOAT;
53401c798c3SYegappan Lakshmanan }
53501c798c3SYegappan Lakshmanan 
53601c798c3SYegappan Lakshmanan /*
53701c798c3SYegappan Lakshmanan  * "tan()" function
53801c798c3SYegappan Lakshmanan  */
53901c798c3SYegappan Lakshmanan     void
f_tan(typval_T * argvars,typval_T * rettv)54001c798c3SYegappan Lakshmanan f_tan(typval_T *argvars, typval_T *rettv)
54101c798c3SYegappan Lakshmanan {
54201c798c3SYegappan Lakshmanan     float_T	f = 0.0;
54301c798c3SYegappan Lakshmanan 
5444490ec4eSYegappan Lakshmanan     if (in_vim9script() && check_for_float_or_nr_arg(argvars, 0) == FAIL)
5454490ec4eSYegappan Lakshmanan 	return;
5464490ec4eSYegappan Lakshmanan 
54701c798c3SYegappan Lakshmanan     rettv->v_type = VAR_FLOAT;
54801c798c3SYegappan Lakshmanan     if (get_float_arg(argvars, &f) == OK)
54901c798c3SYegappan Lakshmanan 	rettv->vval.v_float = tan(f);
55001c798c3SYegappan Lakshmanan     else
55101c798c3SYegappan Lakshmanan 	rettv->vval.v_float = 0.0;
55201c798c3SYegappan Lakshmanan }
55301c798c3SYegappan Lakshmanan 
55401c798c3SYegappan Lakshmanan /*
55501c798c3SYegappan Lakshmanan  * "tanh()" function
55601c798c3SYegappan Lakshmanan  */
55701c798c3SYegappan Lakshmanan     void
f_tanh(typval_T * argvars,typval_T * rettv)55801c798c3SYegappan Lakshmanan f_tanh(typval_T *argvars, typval_T *rettv)
55901c798c3SYegappan Lakshmanan {
56001c798c3SYegappan Lakshmanan     float_T	f = 0.0;
56101c798c3SYegappan Lakshmanan 
5624490ec4eSYegappan Lakshmanan     if (in_vim9script() && check_for_float_or_nr_arg(argvars, 0) == FAIL)
5634490ec4eSYegappan Lakshmanan 	return;
5644490ec4eSYegappan Lakshmanan 
56501c798c3SYegappan Lakshmanan     rettv->v_type = VAR_FLOAT;
56601c798c3SYegappan Lakshmanan     if (get_float_arg(argvars, &f) == OK)
56701c798c3SYegappan Lakshmanan 	rettv->vval.v_float = tanh(f);
56801c798c3SYegappan Lakshmanan     else
56901c798c3SYegappan Lakshmanan 	rettv->vval.v_float = 0.0;
57001c798c3SYegappan Lakshmanan }
57101c798c3SYegappan Lakshmanan 
57201c798c3SYegappan Lakshmanan /*
57301c798c3SYegappan Lakshmanan  * "trunc({float})" function
57401c798c3SYegappan Lakshmanan  */
57501c798c3SYegappan Lakshmanan     void
f_trunc(typval_T * argvars,typval_T * rettv)57601c798c3SYegappan Lakshmanan f_trunc(typval_T *argvars, typval_T *rettv)
57701c798c3SYegappan Lakshmanan {
57801c798c3SYegappan Lakshmanan     float_T	f = 0.0;
57901c798c3SYegappan Lakshmanan 
5804490ec4eSYegappan Lakshmanan     if (in_vim9script() && check_for_float_or_nr_arg(argvars, 0) == FAIL)
5814490ec4eSYegappan Lakshmanan 	return;
5824490ec4eSYegappan Lakshmanan 
58301c798c3SYegappan Lakshmanan     rettv->v_type = VAR_FLOAT;
58401c798c3SYegappan Lakshmanan     if (get_float_arg(argvars, &f) == OK)
58501c798c3SYegappan Lakshmanan 	// trunc() is not in C90, use floor() or ceil() instead.
58601c798c3SYegappan Lakshmanan 	rettv->vval.v_float = f > 0 ? floor(f) : ceil(f);
58701c798c3SYegappan Lakshmanan     else
58801c798c3SYegappan Lakshmanan 	rettv->vval.v_float = 0.0;
58901c798c3SYegappan Lakshmanan }
59001c798c3SYegappan Lakshmanan 
59101c798c3SYegappan Lakshmanan #endif
592