comparison src/floatfns.c @ 88155:d7ddb3e565de

sync with trunk
author Henrik Enberg <henrik.enberg@telia.com>
date Mon, 16 Jan 2006 00:03:54 +0000
parents 23a1cea22d13
children
comparison
equal deleted inserted replaced
88154:8ce476d3ba36 88155:d7ddb3e565de
1 /* Primitive operations on floating point for GNU Emacs Lisp interpreter. 1 /* Primitive operations on floating point for GNU Emacs Lisp interpreter.
2 Copyright (C) 1988, 1993, 1994, 1999 Free Software Foundation, Inc. 2 Copyright (C) 1988, 1993, 1994, 1999, 2002, 2003, 2004,
3 2005 Free Software Foundation, Inc.
3 4
4 This file is part of GNU Emacs. 5 This file is part of GNU Emacs.
5 6
6 GNU Emacs is free software; you can redistribute it and/or modify 7 GNU Emacs is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by 8 it under the terms of the GNU General Public License as published by
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details. 15 GNU General Public License for more details.
15 16
16 You should have received a copy of the GNU General Public License 17 You should have received a copy of the GNU General Public License
17 along with GNU Emacs; see the file COPYING. If not, write to 18 along with GNU Emacs; see the file COPYING. If not, write to
18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 19 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 Boston, MA 02111-1307, USA. */ 20 Boston, MA 02110-1301, USA. */
20 21
21 22
22 /* ANSI C requires only these float functions: 23 /* ANSI C requires only these float functions:
23 acos, asin, atan, atan2, ceil, cos, cosh, exp, fabs, floor, fmod, 24 acos, asin, atan, atan2, ceil, cos, cosh, exp, fabs, floor, fmod,
24 frexp, ldexp, log, log10, modf, pow, sin, sinh, sqrt, tan, tanh. 25 frexp, ldexp, log, log10, modf, pow, sin, sinh, sqrt, tan, tanh.
458 double f1, f2; 459 double f1, f2;
459 460
460 CHECK_NUMBER_OR_FLOAT (arg1); 461 CHECK_NUMBER_OR_FLOAT (arg1);
461 CHECK_NUMBER_OR_FLOAT (arg2); 462 CHECK_NUMBER_OR_FLOAT (arg2);
462 if (INTEGERP (arg1) /* common lisp spec */ 463 if (INTEGERP (arg1) /* common lisp spec */
463 && INTEGERP (arg2)) /* don't promote, if both are ints */ 464 && INTEGERP (arg2) /* don't promote, if both are ints, and */
465 && 0 <= XINT (arg2)) /* we are sure the result is not fractional */
464 { /* this can be improved by pre-calculating */ 466 { /* this can be improved by pre-calculating */
465 EMACS_INT acc, x, y; /* some binary powers of x then accumulating */ 467 EMACS_INT acc, x, y; /* some binary powers of x then accumulating */
466 Lisp_Object val; 468 Lisp_Object val;
467 469
468 x = XINT (arg1); 470 x = XINT (arg1);
504 return make_float (f1); 506 return make_float (f1);
505 } 507 }
506 508
507 DEFUN ("log", Flog, Slog, 1, 2, 0, 509 DEFUN ("log", Flog, Slog, 1, 2, 0,
508 doc: /* Return the natural logarithm of ARG. 510 doc: /* Return the natural logarithm of ARG.
509 If second optional argument BASE is given, return log ARG using that base. */) 511 If the optional argument BASE is given, return log ARG using that base. */)
510 (arg, base) 512 (arg, base)
511 register Lisp_Object arg, base; 513 register Lisp_Object arg, base;
512 { 514 {
513 double d = extract_float (arg); 515 double d = extract_float (arg);
514 516
690 Lisp_Object val; 692 Lisp_Object val;
691 EMACS_INT value; 693 EMACS_INT value;
692 double f = extract_float (arg); 694 double f = extract_float (arg);
693 695
694 if (f == 0.0) 696 if (f == 0.0)
695 value = -(VALMASK >> 1); 697 value = MOST_NEGATIVE_FIXNUM;
696 else 698 else
697 { 699 {
698 #ifdef HAVE_LOGB 700 #ifdef HAVE_LOGB
699 IN_FLOAT (value = logb (f), "logb", arg); 701 IN_FLOAT (value = logb (f), "logb", arg);
700 #else 702 #else
859 return rounding_driver (arg, divisor, ceil, ceiling2, "ceiling"); 861 return rounding_driver (arg, divisor, ceil, ceiling2, "ceiling");
860 } 862 }
861 863
862 DEFUN ("floor", Ffloor, Sfloor, 1, 2, 0, 864 DEFUN ("floor", Ffloor, Sfloor, 1, 2, 0,
863 doc: /* Return the largest integer no greater than ARG. 865 doc: /* Return the largest integer no greater than ARG.
864 This rounds the value towards +inf. 866 This rounds the value towards -inf.
865 With optional DIVISOR, return the largest integer no greater than ARG/DIVISOR. */) 867 With optional DIVISOR, return the largest integer no greater than ARG/DIVISOR. */)
866 (arg, divisor) 868 (arg, divisor)
867 Lisp_Object arg, divisor; 869 Lisp_Object arg, divisor;
868 { 870 {
869 return rounding_driver (arg, divisor, floor, floor2, "floor"); 871 return rounding_driver (arg, divisor, floor, floor2, "floor");
979 #else 981 #else
980 /* Must reestablish handler each time it is called. */ 982 /* Must reestablish handler each time it is called. */
981 signal (SIGILL, float_error); 983 signal (SIGILL, float_error);
982 #endif /* BSD_SYSTEM */ 984 #endif /* BSD_SYSTEM */
983 985
986 SIGNAL_THREAD_CHECK (signo);
984 in_float = 0; 987 in_float = 0;
985 988
986 Fsignal (Qarith_error, Fcons (float_error_arg, Qnil)); 989 Fsignal (Qarith_error, Fcons (float_error_arg, Qnil));
987 } 990 }
988 991
1073 defsubr (&Sceiling); 1076 defsubr (&Sceiling);
1074 defsubr (&Sfloor); 1077 defsubr (&Sfloor);
1075 defsubr (&Sround); 1078 defsubr (&Sround);
1076 defsubr (&Struncate); 1079 defsubr (&Struncate);
1077 } 1080 }
1081
1082 /* arch-tag: be05bf9d-049e-4e31-91b9-e6153d483ae7
1083 (do not change this comment) */