Mercurial > vim
comparison src/float.c @ 24780:7bc92a651472 v8.2.2928
patch 8.2.2928: the evalfunc.c file is too big
Commit: https://github.com/vim/vim/commit/01c798c31a94a50ad0c4a022fc21c1a31553be21
Author: Yegappan Lakshmanan <yegappan@yahoo.com>
Date: Wed Jun 2 17:07:18 2021 +0200
patch 8.2.2928: the evalfunc.c file is too big
Problem: The evalfunc.c file is too big.
Solution: Move float related functionality to a separate file. (Yegappan
Lakshmanan, closes #8287)
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Wed, 02 Jun 2021 17:15:03 +0200 |
parents | |
children | 5f8dd7b3ae41 |
comparison
equal
deleted
inserted
replaced
24779:3675d97a795e | 24780:7bc92a651472 |
---|---|
1 /* vi:set ts=8 sts=4 sw=4 noet: | |
2 * | |
3 * VIM - Vi IMproved by Bram Moolenaar | |
4 * | |
5 * Do ":help uganda" in Vim to read copying and usage conditions. | |
6 * Do ":help credits" in Vim to see a list of people who contributed. | |
7 * See README.txt for an overview of the Vim source code. | |
8 */ | |
9 | |
10 /* | |
11 * float.c: Floating point functions | |
12 */ | |
13 #define USING_FLOAT_STUFF | |
14 | |
15 #include "vim.h" | |
16 | |
17 #if (defined(FEAT_EVAL) && defined(FEAT_FLOAT)) || defined(PROTO) | |
18 | |
19 #ifdef VMS | |
20 # include <float.h> | |
21 #endif | |
22 | |
23 /* | |
24 * Convert the string "text" to a floating point number. | |
25 * This uses strtod(). setlocale(LC_NUMERIC, "C") has been used to make sure | |
26 * this always uses a decimal point. | |
27 * Returns the length of the text that was consumed. | |
28 */ | |
29 int | |
30 string2float( | |
31 char_u *text, | |
32 float_T *value) // result stored here | |
33 { | |
34 char *s = (char *)text; | |
35 float_T f; | |
36 | |
37 // MS-Windows does not deal with "inf" and "nan" properly. | |
38 if (STRNICMP(text, "inf", 3) == 0) | |
39 { | |
40 *value = INFINITY; | |
41 return 3; | |
42 } | |
43 if (STRNICMP(text, "-inf", 3) == 0) | |
44 { | |
45 *value = -INFINITY; | |
46 return 4; | |
47 } | |
48 if (STRNICMP(text, "nan", 3) == 0) | |
49 { | |
50 *value = NAN; | |
51 return 3; | |
52 } | |
53 f = strtod(s, &s); | |
54 *value = f; | |
55 return (int)((char_u *)s - text); | |
56 } | |
57 | |
58 /* | |
59 * Get the float value of "argvars[0]" into "f". | |
60 * Returns FAIL when the argument is not a Number or Float. | |
61 */ | |
62 static int | |
63 get_float_arg(typval_T *argvars, float_T *f) | |
64 { | |
65 if (argvars[0].v_type == VAR_FLOAT) | |
66 { | |
67 *f = argvars[0].vval.v_float; | |
68 return OK; | |
69 } | |
70 if (argvars[0].v_type == VAR_NUMBER) | |
71 { | |
72 *f = (float_T)argvars[0].vval.v_number; | |
73 return OK; | |
74 } | |
75 emsg(_("E808: Number or Float required")); | |
76 return FAIL; | |
77 } | |
78 | |
79 /* | |
80 * "abs(expr)" function | |
81 */ | |
82 void | |
83 f_abs(typval_T *argvars, typval_T *rettv) | |
84 { | |
85 if (argvars[0].v_type == VAR_FLOAT) | |
86 { | |
87 rettv->v_type = VAR_FLOAT; | |
88 rettv->vval.v_float = fabs(argvars[0].vval.v_float); | |
89 } | |
90 else | |
91 { | |
92 varnumber_T n; | |
93 int error = FALSE; | |
94 | |
95 n = tv_get_number_chk(&argvars[0], &error); | |
96 if (error) | |
97 rettv->vval.v_number = -1; | |
98 else if (n > 0) | |
99 rettv->vval.v_number = n; | |
100 else | |
101 rettv->vval.v_number = -n; | |
102 } | |
103 } | |
104 | |
105 /* | |
106 * "acos()" function | |
107 */ | |
108 void | |
109 f_acos(typval_T *argvars, typval_T *rettv) | |
110 { | |
111 float_T f = 0.0; | |
112 | |
113 rettv->v_type = VAR_FLOAT; | |
114 if (get_float_arg(argvars, &f) == OK) | |
115 rettv->vval.v_float = acos(f); | |
116 else | |
117 rettv->vval.v_float = 0.0; | |
118 } | |
119 | |
120 /* | |
121 * "asin()" function | |
122 */ | |
123 void | |
124 f_asin(typval_T *argvars, typval_T *rettv) | |
125 { | |
126 float_T f = 0.0; | |
127 | |
128 rettv->v_type = VAR_FLOAT; | |
129 if (get_float_arg(argvars, &f) == OK) | |
130 rettv->vval.v_float = asin(f); | |
131 else | |
132 rettv->vval.v_float = 0.0; | |
133 } | |
134 | |
135 /* | |
136 * "atan()" function | |
137 */ | |
138 void | |
139 f_atan(typval_T *argvars, typval_T *rettv) | |
140 { | |
141 float_T f = 0.0; | |
142 | |
143 rettv->v_type = VAR_FLOAT; | |
144 if (get_float_arg(argvars, &f) == OK) | |
145 rettv->vval.v_float = atan(f); | |
146 else | |
147 rettv->vval.v_float = 0.0; | |
148 } | |
149 | |
150 /* | |
151 * "atan2()" function | |
152 */ | |
153 void | |
154 f_atan2(typval_T *argvars, typval_T *rettv) | |
155 { | |
156 float_T fx = 0.0, fy = 0.0; | |
157 | |
158 rettv->v_type = VAR_FLOAT; | |
159 if (get_float_arg(argvars, &fx) == OK | |
160 && get_float_arg(&argvars[1], &fy) == OK) | |
161 rettv->vval.v_float = atan2(fx, fy); | |
162 else | |
163 rettv->vval.v_float = 0.0; | |
164 } | |
165 | |
166 /* | |
167 * "ceil({float})" function | |
168 */ | |
169 void | |
170 f_ceil(typval_T *argvars, typval_T *rettv) | |
171 { | |
172 float_T f = 0.0; | |
173 | |
174 rettv->v_type = VAR_FLOAT; | |
175 if (get_float_arg(argvars, &f) == OK) | |
176 rettv->vval.v_float = ceil(f); | |
177 else | |
178 rettv->vval.v_float = 0.0; | |
179 } | |
180 | |
181 /* | |
182 * "cos()" function | |
183 */ | |
184 void | |
185 f_cos(typval_T *argvars, typval_T *rettv) | |
186 { | |
187 float_T f = 0.0; | |
188 | |
189 rettv->v_type = VAR_FLOAT; | |
190 if (get_float_arg(argvars, &f) == OK) | |
191 rettv->vval.v_float = cos(f); | |
192 else | |
193 rettv->vval.v_float = 0.0; | |
194 } | |
195 | |
196 /* | |
197 * "cosh()" function | |
198 */ | |
199 void | |
200 f_cosh(typval_T *argvars, typval_T *rettv) | |
201 { | |
202 float_T f = 0.0; | |
203 | |
204 rettv->v_type = VAR_FLOAT; | |
205 if (get_float_arg(argvars, &f) == OK) | |
206 rettv->vval.v_float = cosh(f); | |
207 else | |
208 rettv->vval.v_float = 0.0; | |
209 } | |
210 | |
211 /* | |
212 * "exp()" function | |
213 */ | |
214 void | |
215 f_exp(typval_T *argvars, typval_T *rettv) | |
216 { | |
217 float_T f = 0.0; | |
218 | |
219 rettv->v_type = VAR_FLOAT; | |
220 if (get_float_arg(argvars, &f) == OK) | |
221 rettv->vval.v_float = exp(f); | |
222 else | |
223 rettv->vval.v_float = 0.0; | |
224 } | |
225 | |
226 /* | |
227 * "float2nr({float})" function | |
228 */ | |
229 void | |
230 f_float2nr(typval_T *argvars, typval_T *rettv) | |
231 { | |
232 float_T f = 0.0; | |
233 | |
234 if (get_float_arg(argvars, &f) == OK) | |
235 { | |
236 if (f <= (float_T)-VARNUM_MAX + DBL_EPSILON) | |
237 rettv->vval.v_number = -VARNUM_MAX; | |
238 else if (f >= (float_T)VARNUM_MAX - DBL_EPSILON) | |
239 rettv->vval.v_number = VARNUM_MAX; | |
240 else | |
241 rettv->vval.v_number = (varnumber_T)f; | |
242 } | |
243 } | |
244 | |
245 /* | |
246 * "floor({float})" function | |
247 */ | |
248 void | |
249 f_floor(typval_T *argvars, typval_T *rettv) | |
250 { | |
251 float_T f = 0.0; | |
252 | |
253 rettv->v_type = VAR_FLOAT; | |
254 if (get_float_arg(argvars, &f) == OK) | |
255 rettv->vval.v_float = floor(f); | |
256 else | |
257 rettv->vval.v_float = 0.0; | |
258 } | |
259 | |
260 /* | |
261 * "fmod()" function | |
262 */ | |
263 void | |
264 f_fmod(typval_T *argvars, typval_T *rettv) | |
265 { | |
266 float_T fx = 0.0, fy = 0.0; | |
267 | |
268 rettv->v_type = VAR_FLOAT; | |
269 if (get_float_arg(argvars, &fx) == OK | |
270 && get_float_arg(&argvars[1], &fy) == OK) | |
271 rettv->vval.v_float = fmod(fx, fy); | |
272 else | |
273 rettv->vval.v_float = 0.0; | |
274 } | |
275 | |
276 # if defined(HAVE_MATH_H) || defined(PROTO) | |
277 /* | |
278 * "isinf()" function | |
279 */ | |
280 void | |
281 f_isinf(typval_T *argvars, typval_T *rettv) | |
282 { | |
283 if (argvars[0].v_type == VAR_FLOAT && isinf(argvars[0].vval.v_float)) | |
284 rettv->vval.v_number = argvars[0].vval.v_float > 0.0 ? 1 : -1; | |
285 } | |
286 | |
287 /* | |
288 * "isnan()" function | |
289 */ | |
290 void | |
291 f_isnan(typval_T *argvars, typval_T *rettv) | |
292 { | |
293 rettv->vval.v_number = argvars[0].v_type == VAR_FLOAT | |
294 && isnan(argvars[0].vval.v_float); | |
295 } | |
296 # endif | |
297 | |
298 /* | |
299 * "log()" function | |
300 */ | |
301 void | |
302 f_log(typval_T *argvars, typval_T *rettv) | |
303 { | |
304 float_T f = 0.0; | |
305 | |
306 rettv->v_type = VAR_FLOAT; | |
307 if (get_float_arg(argvars, &f) == OK) | |
308 rettv->vval.v_float = log(f); | |
309 else | |
310 rettv->vval.v_float = 0.0; | |
311 } | |
312 | |
313 /* | |
314 * "log10()" function | |
315 */ | |
316 void | |
317 f_log10(typval_T *argvars, typval_T *rettv) | |
318 { | |
319 float_T f = 0.0; | |
320 | |
321 rettv->v_type = VAR_FLOAT; | |
322 if (get_float_arg(argvars, &f) == OK) | |
323 rettv->vval.v_float = log10(f); | |
324 else | |
325 rettv->vval.v_float = 0.0; | |
326 } | |
327 | |
328 /* | |
329 * "pow()" function | |
330 */ | |
331 void | |
332 f_pow(typval_T *argvars, typval_T *rettv) | |
333 { | |
334 float_T fx = 0.0, fy = 0.0; | |
335 | |
336 rettv->v_type = VAR_FLOAT; | |
337 if (get_float_arg(argvars, &fx) == OK | |
338 && get_float_arg(&argvars[1], &fy) == OK) | |
339 rettv->vval.v_float = pow(fx, fy); | |
340 else | |
341 rettv->vval.v_float = 0.0; | |
342 } | |
343 | |
344 | |
345 /* | |
346 * round() is not in C90, use ceil() or floor() instead. | |
347 */ | |
348 float_T | |
349 vim_round(float_T f) | |
350 { | |
351 return f > 0 ? floor(f + 0.5) : ceil(f - 0.5); | |
352 } | |
353 | |
354 /* | |
355 * "round({float})" function | |
356 */ | |
357 void | |
358 f_round(typval_T *argvars, typval_T *rettv) | |
359 { | |
360 float_T f = 0.0; | |
361 | |
362 rettv->v_type = VAR_FLOAT; | |
363 if (get_float_arg(argvars, &f) == OK) | |
364 rettv->vval.v_float = vim_round(f); | |
365 else | |
366 rettv->vval.v_float = 0.0; | |
367 } | |
368 | |
369 /* | |
370 * "sin()" function | |
371 */ | |
372 void | |
373 f_sin(typval_T *argvars, typval_T *rettv) | |
374 { | |
375 float_T f = 0.0; | |
376 | |
377 rettv->v_type = VAR_FLOAT; | |
378 if (get_float_arg(argvars, &f) == OK) | |
379 rettv->vval.v_float = sin(f); | |
380 else | |
381 rettv->vval.v_float = 0.0; | |
382 } | |
383 | |
384 /* | |
385 * "sinh()" function | |
386 */ | |
387 void | |
388 f_sinh(typval_T *argvars, typval_T *rettv) | |
389 { | |
390 float_T f = 0.0; | |
391 | |
392 rettv->v_type = VAR_FLOAT; | |
393 if (get_float_arg(argvars, &f) == OK) | |
394 rettv->vval.v_float = sinh(f); | |
395 else | |
396 rettv->vval.v_float = 0.0; | |
397 } | |
398 | |
399 /* | |
400 * "sqrt()" function | |
401 */ | |
402 void | |
403 f_sqrt(typval_T *argvars, typval_T *rettv) | |
404 { | |
405 float_T f = 0.0; | |
406 | |
407 rettv->v_type = VAR_FLOAT; | |
408 if (get_float_arg(argvars, &f) == OK) | |
409 rettv->vval.v_float = sqrt(f); | |
410 else | |
411 rettv->vval.v_float = 0.0; | |
412 } | |
413 | |
414 /* | |
415 * "str2float()" function | |
416 */ | |
417 void | |
418 f_str2float(typval_T *argvars, typval_T *rettv) | |
419 { | |
420 char_u *p = skipwhite(tv_get_string(&argvars[0])); | |
421 int isneg = (*p == '-'); | |
422 | |
423 if (*p == '+' || *p == '-') | |
424 p = skipwhite(p + 1); | |
425 (void)string2float(p, &rettv->vval.v_float); | |
426 if (isneg) | |
427 rettv->vval.v_float *= -1; | |
428 rettv->v_type = VAR_FLOAT; | |
429 } | |
430 | |
431 /* | |
432 * "tan()" function | |
433 */ | |
434 void | |
435 f_tan(typval_T *argvars, typval_T *rettv) | |
436 { | |
437 float_T f = 0.0; | |
438 | |
439 rettv->v_type = VAR_FLOAT; | |
440 if (get_float_arg(argvars, &f) == OK) | |
441 rettv->vval.v_float = tan(f); | |
442 else | |
443 rettv->vval.v_float = 0.0; | |
444 } | |
445 | |
446 /* | |
447 * "tanh()" function | |
448 */ | |
449 void | |
450 f_tanh(typval_T *argvars, typval_T *rettv) | |
451 { | |
452 float_T f = 0.0; | |
453 | |
454 rettv->v_type = VAR_FLOAT; | |
455 if (get_float_arg(argvars, &f) == OK) | |
456 rettv->vval.v_float = tanh(f); | |
457 else | |
458 rettv->vval.v_float = 0.0; | |
459 } | |
460 | |
461 /* | |
462 * "trunc({float})" function | |
463 */ | |
464 void | |
465 f_trunc(typval_T *argvars, typval_T *rettv) | |
466 { | |
467 float_T f = 0.0; | |
468 | |
469 rettv->v_type = VAR_FLOAT; | |
470 if (get_float_arg(argvars, &f) == OK) | |
471 // trunc() is not in C90, use floor() or ceil() instead. | |
472 rettv->vval.v_float = f > 0 ? floor(f) : ceil(f); | |
473 else | |
474 rettv->vval.v_float = 0.0; | |
475 } | |
476 | |
477 #endif |