This source file includes following definitions.
- CHECK_FLOAT
- extract_float
- DEFUN
- DEFUN
- DEFUN
- DEFUN
- DEFUN
- DEFUN
- DEFUN
- DEFUN
- DEFUN
- DEFUN
- DEFUN
- DEFUN
- double_integer_scale
- rescale_for_division
- rounding_driver
- ceiling2
- floor2
- truncate2
- round2
- rounddiv_q
- emacs_rint
- trunc
- identity
- fmod_float
- DEFUN
- DEFUN
- DEFUN
- DEFUN
- syms_of_floatfns
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51 #include <config.h>
52
53 #include "lisp.h"
54 #include "bignum.h"
55
56 #include <math.h>
57
58
59
60
61
62 #if defined __FINITE_MATH_ONLY__ && __FINITE_MATH_ONLY__
63 #error Emacs cannot be built with -ffinite-math-only
64 #endif
65
66
67
68 static void
69 CHECK_FLOAT (Lisp_Object x)
70 {
71 CHECK_TYPE (FLOATP (x), Qfloatp, x);
72 }
73
74
75
76 double
77 extract_float (Lisp_Object num)
78 {
79 CHECK_NUMBER (num);
80 return XFLOATINT (num);
81 }
82
83
84
85 DEFUN ("acos", Facos, Sacos, 1, 1, 0,
86 doc: )
87 (Lisp_Object arg)
88 {
89 double d = extract_float (arg);
90 d = acos (d);
91 return make_float (d);
92 }
93
94 DEFUN ("asin", Fasin, Sasin, 1, 1, 0,
95 doc: )
96 (Lisp_Object arg)
97 {
98 double d = extract_float (arg);
99 d = asin (d);
100 return make_float (d);
101 }
102
103 DEFUN ("atan", Fatan, Satan, 1, 2, 0,
104 doc:
105
106
107
108 )
109 (Lisp_Object y, Lisp_Object x)
110 {
111 double d = extract_float (y);
112
113 if (NILP (x))
114 d = atan (d);
115 else
116 {
117 double d2 = extract_float (x);
118 d = atan2 (d, d2);
119 }
120 return make_float (d);
121 }
122
123 DEFUN ("cos", Fcos, Scos, 1, 1, 0,
124 doc: )
125 (Lisp_Object arg)
126 {
127 double d = extract_float (arg);
128 d = cos (d);
129 return make_float (d);
130 }
131
132 DEFUN ("sin", Fsin, Ssin, 1, 1, 0,
133 doc: )
134 (Lisp_Object arg)
135 {
136 double d = extract_float (arg);
137 d = sin (d);
138 return make_float (d);
139 }
140
141 DEFUN ("tan", Ftan, Stan, 1, 1, 0,
142 doc: )
143 (Lisp_Object arg)
144 {
145 double d = extract_float (arg);
146 d = tan (d);
147 return make_float (d);
148 }
149
150 DEFUN ("isnan", Fisnan, Sisnan, 1, 1, 0,
151 doc: )
152 (Lisp_Object x)
153 {
154 CHECK_FLOAT (x);
155 return isnan (XFLOAT_DATA (x)) ? Qt : Qnil;
156 }
157
158
159
160 #ifndef signbit
161 # define signbit(x) ((x) < 0 || (IEEE_FLOATING_POINT && !(x) && 1 / (x) < 0))
162 #endif
163
164 DEFUN ("copysign", Fcopysign, Scopysign, 2, 2, 0,
165 doc:
166 )
167 (Lisp_Object x1, Lisp_Object x2)
168 {
169 double f1, f2;
170
171 CHECK_FLOAT (x1);
172 CHECK_FLOAT (x2);
173
174 f1 = XFLOAT_DATA (x1);
175 f2 = XFLOAT_DATA (x2);
176
177
178
179 return signbit (f1) != signbit (f2) ? make_float (-f1) : x1;
180 }
181
182 DEFUN ("frexp", Ffrexp, Sfrexp, 1, 1, 0,
183 doc:
184
185
186
187
188
189
190
191 )
192 (Lisp_Object x)
193 {
194 double f = extract_float (x);
195 int exponent;
196 double sgnfcand = frexp (f, &exponent);
197 return Fcons (make_float (sgnfcand), make_fixnum (exponent));
198 }
199
200 DEFUN ("ldexp", Fldexp, Sldexp, 2, 2, 0,
201 doc:
202 )
203 (Lisp_Object sgnfcand, Lisp_Object exponent)
204 {
205 CHECK_FIXNUM (exponent);
206 int e = min (max (INT_MIN, XFIXNUM (exponent)), INT_MAX);
207 return make_float (ldexp (extract_float (sgnfcand), e));
208 }
209
210 DEFUN ("exp", Fexp, Sexp, 1, 1, 0,
211 doc: )
212 (Lisp_Object arg)
213 {
214 double d = extract_float (arg);
215 d = exp (d);
216 return make_float (d);
217 }
218
219 DEFUN ("expt", Fexpt, Sexpt, 2, 2, 0,
220 doc: )
221 (Lisp_Object arg1, Lisp_Object arg2)
222 {
223 CHECK_NUMBER (arg1);
224 CHECK_NUMBER (arg2);
225
226
227
228 if (INTEGERP (arg1) && !NILP (Fnatnump (arg2)))
229 return expt_integer (arg1, arg2);
230
231 return make_float (pow (XFLOATINT (arg1), XFLOATINT (arg2)));
232 }
233
234 DEFUN ("log", Flog, Slog, 1, 2, 0,
235 doc:
236 )
237 (Lisp_Object arg, Lisp_Object base)
238 {
239 double d = extract_float (arg);
240
241 if (NILP (base))
242 d = log (d);
243 else
244 {
245 double b = extract_float (base);
246
247 if (b == 10.0)
248 d = log10 (d);
249 #if HAVE_LOG2
250 else if (b == 2.0)
251 d = log2 (d);
252 #endif
253 else
254 d = log (d) / log (b);
255 }
256 return make_float (d);
257 }
258
259 DEFUN ("sqrt", Fsqrt, Ssqrt, 1, 1, 0,
260 doc: )
261 (Lisp_Object arg)
262 {
263 double d = extract_float (arg);
264 d = sqrt (d);
265 return make_float (d);
266 }
267
268 DEFUN ("abs", Fabs, Sabs, 1, 1, 0,
269 doc: )
270 (Lisp_Object arg)
271 {
272 CHECK_NUMBER (arg);
273
274 if (FIXNUMP (arg))
275 {
276 if (XFIXNUM (arg) < 0)
277 arg = make_int (-XFIXNUM (arg));
278 }
279 else if (FLOATP (arg))
280 {
281 if (signbit (XFLOAT_DATA (arg)))
282 arg = make_float (- XFLOAT_DATA (arg));
283 }
284 else
285 {
286 if (mpz_sgn (*xbignum_val (arg)) < 0)
287 {
288 mpz_neg (mpz[0], *xbignum_val (arg));
289 arg = make_integer_mpz ();
290 }
291 }
292
293 return arg;
294 }
295
296 DEFUN ("float", Ffloat, Sfloat, 1, 1, 0,
297 doc: )
298 (register Lisp_Object arg)
299 {
300 CHECK_NUMBER (arg);
301
302 return FLOATP (arg) ? arg : make_float (XFLOATINT (arg));
303 }
304
305 DEFUN ("logb", Flogb, Slogb, 1, 1, 0,
306 doc:
307 )
308 (Lisp_Object arg)
309 {
310 EMACS_INT value;
311 CHECK_NUMBER (arg);
312
313 if (FLOATP (arg))
314 {
315 double f = XFLOAT_DATA (arg);
316 if (f == 0)
317 return make_float (-HUGE_VAL);
318 if (!isfinite (f))
319 return f < 0 ? make_float (-f) : arg;
320 int ivalue;
321 frexp (f, &ivalue);
322 value = ivalue - 1;
323 }
324 else if (!FIXNUMP (arg))
325 value = mpz_sizeinbase (*xbignum_val (arg), 2) - 1;
326 else
327 {
328 EMACS_INT i = XFIXNUM (arg);
329 if (i == 0)
330 return make_float (-HUGE_VAL);
331 value = elogb (eabs (i));
332 }
333
334 return make_fixnum (value);
335 }
336
337
338
339
340
341
342
343
344
345 int
346 double_integer_scale (double d)
347 {
348 int exponent = ilogb (d);
349 #ifdef HAIKU
350
351
352
353
354 if (exponent == FP_ILOGB0)
355 {
356 if (isnan (d))
357 return (DBL_MANT_DIG - DBL_MIN_EXP) + 2;
358 if (isinf (d))
359 return (DBL_MANT_DIG - DBL_MIN_EXP) + 1;
360
361 return (DBL_MANT_DIG - DBL_MIN_EXP);
362 }
363 #endif
364 return (DBL_MIN_EXP - 1 <= exponent && exponent < INT_MAX
365 ? DBL_MANT_DIG - 1 - exponent
366 : (DBL_MANT_DIG - DBL_MIN_EXP
367 + (isnan (d) ? 2 : exponent == INT_MAX)));
368 }
369
370
371
372
373
374
375
376
377
378 static mpz_t const *
379 rescale_for_division (Lisp_Object n, mpz_t *t, int nscale, int dscale)
380 {
381 mpz_t const *pn;
382
383 if (FLOATP (n))
384 {
385 if (DBL_MANT_DIG - DBL_MIN_EXP < nscale)
386 overflow_error ();
387 mpz_set_d (*t, scalbn (XFLOAT_DATA (n), nscale));
388 pn = t;
389 }
390 else
391 pn = bignum_integer (t, n);
392
393 if (nscale < dscale)
394 {
395 emacs_mpz_mul_2exp (*t, *pn, (dscale - nscale) * LOG2_FLT_RADIX);
396 pn = t;
397 }
398 return pn;
399 }
400
401
402
403 static Lisp_Object
404 rounding_driver (Lisp_Object n, Lisp_Object d,
405 double (*double_round) (double),
406 void (*int_divide) (mpz_t, mpz_t const, mpz_t const),
407 EMACS_INT (*fixnum_divide) (EMACS_INT, EMACS_INT))
408 {
409 CHECK_NUMBER (n);
410
411 if (NILP (d))
412 return FLOATP (n) ? double_to_integer (double_round (XFLOAT_DATA (n))) : n;
413
414 CHECK_NUMBER (d);
415
416 int dscale = 0;
417 if (FIXNUMP (d))
418 {
419 if (XFIXNUM (d) == 0)
420 xsignal0 (Qarith_error);
421
422
423 if (FIXNUMP (n))
424 return make_int (fixnum_divide (XFIXNUM (n), XFIXNUM (d)));
425 }
426 else if (FLOATP (d))
427 {
428 if (XFLOAT_DATA (d) == 0)
429 xsignal0 (Qarith_error);
430 dscale = double_integer_scale (XFLOAT_DATA (d));
431 }
432
433 int nscale = FLOATP (n) ? double_integer_scale (XFLOAT_DATA (n)) : 0;
434
435
436
437
438 if (dscale == DBL_MANT_DIG - DBL_MIN_EXP + 1 && nscale < dscale)
439 return make_fixnum (0);
440
441 int_divide (mpz[0],
442 *rescale_for_division (n, &mpz[0], nscale, dscale),
443 *rescale_for_division (d, &mpz[1], dscale, nscale));
444 return make_integer_mpz ();
445 }
446
447 static EMACS_INT
448 ceiling2 (EMACS_INT n, EMACS_INT d)
449 {
450 return n / d + ((n % d != 0) & ((n < 0) == (d < 0)));
451 }
452
453 static EMACS_INT
454 floor2 (EMACS_INT n, EMACS_INT d)
455 {
456 return n / d - ((n % d != 0) & ((n < 0) != (d < 0)));
457 }
458
459 static EMACS_INT
460 truncate2 (EMACS_INT n, EMACS_INT d)
461 {
462 return n / d;
463 }
464
465 static EMACS_INT
466 round2 (EMACS_INT n, EMACS_INT d)
467 {
468
469
470
471
472
473 EMACS_INT q = n / d;
474 EMACS_INT r = n % d;
475 bool neg_d = d < 0;
476 bool neg_r = r < 0;
477 EMACS_INT abs_r = eabs (r);
478 EMACS_INT abs_r1 = eabs (d) - abs_r;
479 if (abs_r1 < abs_r + (q & 1))
480 q += neg_d == neg_r ? 1 : -1;
481 return q;
482 }
483
484 static void
485 rounddiv_q (mpz_t q, mpz_t const n, mpz_t const d)
486 {
487
488 mpz_t *r = &mpz[2], *abs_r = r, *abs_r1 = &mpz[3];
489 mpz_tdiv_qr (q, *r, n, d);
490 bool neg_d = mpz_sgn (d) < 0;
491 bool neg_r = mpz_sgn (*r) < 0;
492 mpz_abs (*abs_r, *r);
493 mpz_abs (*abs_r1, d);
494 mpz_sub (*abs_r1, *abs_r1, *abs_r);
495 if (mpz_cmp (*abs_r1, *abs_r) < (mpz_odd_p (q) != 0))
496 (neg_d == neg_r ? mpz_add_ui : mpz_sub_ui) (q, q, 1);
497 }
498
499
500
501 #ifdef HAVE_RINT
502 #define emacs_rint rint
503 #else
504 static double
505 emacs_rint (double d)
506 {
507 double d1 = d + 0.5;
508 double r = floor (d1);
509 return r - (r == d1 && fmod (r, 2) != 0);
510 }
511 #endif
512
513 #ifndef HAVE_TRUNC
514 double
515 trunc (double d)
516 {
517 return (d < 0 ? ceil : floor) (d);
518 }
519 #endif
520
521 DEFUN ("ceiling", Fceiling, Sceiling, 1, 2, 0,
522 doc:
523
524 )
525 (Lisp_Object arg, Lisp_Object divisor)
526 {
527 return rounding_driver (arg, divisor, ceil, mpz_cdiv_q, ceiling2);
528 }
529
530 DEFUN ("floor", Ffloor, Sfloor, 1, 2, 0,
531 doc:
532
533 )
534 (Lisp_Object arg, Lisp_Object divisor)
535 {
536 return rounding_driver (arg, divisor, floor, mpz_fdiv_q, floor2);
537 }
538
539 DEFUN ("round", Fround, Sround, 1, 2, 0,
540 doc:
541
542
543
544
545
546 )
547 (Lisp_Object arg, Lisp_Object divisor)
548 {
549 return rounding_driver (arg, divisor, emacs_rint, rounddiv_q, round2);
550 }
551
552
553 static double
554 identity (double x)
555 {
556 return x;
557 }
558
559 DEFUN ("truncate", Ftruncate, Struncate, 1, 2, 0,
560 doc:
561
562 )
563 (Lisp_Object arg, Lisp_Object divisor)
564 {
565 return rounding_driver (arg, divisor, identity, mpz_tdiv_q, truncate2);
566 }
567
568
569 Lisp_Object
570 fmod_float (Lisp_Object x, Lisp_Object y)
571 {
572 double f1 = XFLOATINT (x);
573 double f2 = XFLOATINT (y);
574
575 f1 = fmod (f1, f2);
576
577
578 if (f2 < 0 ? f1 > 0 : f1 < 0)
579 f1 += f2;
580
581 return make_float (f1);
582 }
583
584 DEFUN ("fceiling", Ffceiling, Sfceiling, 1, 1, 0,
585 doc:
586 )
587 (Lisp_Object arg)
588 {
589 CHECK_FLOAT (arg);
590 double d = XFLOAT_DATA (arg);
591 d = ceil (d);
592 return make_float (d);
593 }
594
595 DEFUN ("ffloor", Fffloor, Sffloor, 1, 1, 0,
596 doc:
597 )
598 (Lisp_Object arg)
599 {
600 CHECK_FLOAT (arg);
601 double d = XFLOAT_DATA (arg);
602 d = floor (d);
603 return make_float (d);
604 }
605
606 DEFUN ("fround", Ffround, Sfround, 1, 1, 0,
607 doc: )
608 (Lisp_Object arg)
609 {
610 CHECK_FLOAT (arg);
611 double d = XFLOAT_DATA (arg);
612 d = emacs_rint (d);
613 return make_float (d);
614 }
615
616 DEFUN ("ftruncate", Fftruncate, Sftruncate, 1, 1, 0,
617 doc:
618 )
619 (Lisp_Object arg)
620 {
621 CHECK_FLOAT (arg);
622 double d = XFLOAT_DATA (arg);
623 d = trunc (d);
624 return make_float (d);
625 }
626
627 void
628 syms_of_floatfns (void)
629 {
630 defsubr (&Sacos);
631 defsubr (&Sasin);
632 defsubr (&Satan);
633 defsubr (&Scos);
634 defsubr (&Ssin);
635 defsubr (&Stan);
636 defsubr (&Sisnan);
637 defsubr (&Scopysign);
638 defsubr (&Sfrexp);
639 defsubr (&Sldexp);
640 defsubr (&Sfceiling);
641 defsubr (&Sffloor);
642 defsubr (&Sfround);
643 defsubr (&Sftruncate);
644 defsubr (&Sexp);
645 defsubr (&Sexpt);
646 defsubr (&Slog);
647 defsubr (&Ssqrt);
648
649 defsubr (&Sabs);
650 defsubr (&Sfloat);
651 defsubr (&Slogb);
652 defsubr (&Sceiling);
653 defsubr (&Sfloor);
654 defsubr (&Sround);
655 defsubr (&Struncate);
656 }