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