comparison src/number.c @ 5911:48386fd60fd0

GMP functions that take doubles choke on non-finite values, avoid that. src/ChangeLog addition: 2015-05-10 Aidan Kehoe <kehoea@parhasard.net> * floatfns.c (double_to_integer): Rename this from float_to_int to fit our newer, bignum-compatible terminology. GMP can signal SIGFPE when asked to turn NaN or infinity into a bignum, and we're not prepared to handle that signal if the OS float library routines don't do that, so check for those values explicitly. * floatfns.c (ceiling_two_float): * floatfns.c (ceiling_one_float): * floatfns.c (floor_two_float): * floatfns.c (floor_one_float): * floatfns.c (round_two_float): * floatfns.c (round_one_float): * floatfns.c (truncate_two_float): * floatfns.c (truncate_one_float): Call double_to_integer() with its new name. * number.c: Don't use the {bignum,ratio,bigfloat}_set_double functions directly here, with GMP they can choke when handed non-finite C doubles, call Ftruncate() and the new float_to_bigfloat() from floatfns.c. Maybe we should extend number-gmp.c with GMP-specific implementations that check for non-finite values. tests/ChangeLog addition: 2015-05-10 Aidan Kehoe <kehoea@parhasard.net> * automated/lisp-tests.el: Backslash a few parentheses in the first column for the sake of fontification. * automated/lisp-tests.el: Check that the rounding functions signal Lisp errors correctly when handed positive and negative infinity and NaN.
author Aidan Kehoe <kehoea@parhasard.net>
date Sun, 10 May 2015 19:07:09 +0100
parents 6174848f3e6c
children
comparison
equal deleted inserted replaced
5910:eb1e15c9440b 5911:48386fd60fd0
306 DEFINE_DUMPABLE_FROB_BLOCK_LISP_OBJECT ("bigfloat", bigfloat, 0, 306 DEFINE_DUMPABLE_FROB_BLOCK_LISP_OBJECT ("bigfloat", bigfloat, 0,
307 bigfloat_print, 307 bigfloat_print,
308 IF_NEW_GC (bigfloat_finalize), 308 IF_NEW_GC (bigfloat_finalize),
309 bigfloat_equal, bigfloat_hash, 309 bigfloat_equal, bigfloat_hash,
310 bigfloat_description, Lisp_Bigfloat); 310 bigfloat_description, Lisp_Bigfloat);
311
312 extern Lisp_Object float_to_bigfloat (const Ascbyte *, Lisp_Object,
313 unsigned long);
311 314
312 #endif /* HAVE_BIGFLOAT */ 315 #endif /* HAVE_BIGFLOAT */
313 316
314 Lisp_Object Qbigfloatp; 317 Lisp_Object Qbigfloatp;
315 318
599 { 602 {
600 case FIXNUM_T: 603 case FIXNUM_T:
601 return Ftruncate (number, Qnil); 604 return Ftruncate (number, Qnil);
602 case BIGNUM_T: 605 case BIGNUM_T:
603 #ifdef HAVE_BIGNUM 606 #ifdef HAVE_BIGNUM
604 bignum_set_double (scratch_bignum, XFLOAT_DATA (number)); 607 {
605 return make_bignum_bg (scratch_bignum); 608 Lisp_Object truncate = Ftruncate (number, Qnil);
609 return FIXNUMP (truncate) ?
610 make_bignum (XREALFIXNUM (truncate)) : truncate;
611 }
606 #else 612 #else
607 ABORT (); 613 ABORT ();
608 #endif /* HAVE_BIGNUM */ 614 #endif /* HAVE_BIGNUM */
609 case RATIO_T: 615 case RATIO_T:
610 #ifdef HAVE_RATIO 616 #ifdef HAVE_RATIO
611 ratio_set_double (scratch_ratio, XFLOAT_DATA (number)); 617 {
612 return make_ratio_rt (scratch_ratio); 618 Lisp_Object truncate = Ftruncate (number, Qnil);
619 if (FIXNUMP (truncate))
620 {
621 return make_ratio (XREALFIXNUM (truncate), 1UL);
622 }
623
624 bignum_set_long (scratch_bignum, 1L);
625 return make_ratio_bg (XBIGNUM_DATA (truncate), scratch_bignum);
626 }
613 #else 627 #else
614 ABORT (); 628 ABORT ();
615 #endif /* HAVE_RATIO */ 629 #endif /* HAVE_RATIO */
616 case FLOAT_T: 630 case FLOAT_T:
617 return number; 631 return number;
618 case BIGFLOAT_T: 632 case BIGFLOAT_T:
619 #ifdef HAVE_BIGFLOAT 633 #ifdef HAVE_BIGFLOAT
620 bigfloat_set_prec (scratch_bigfloat, precision); 634 return float_to_bigfloat ("coerce-number", number, precision);
621 bigfloat_set_double (scratch_bigfloat, XFLOAT_DATA (number));
622 return make_bigfloat_bf (scratch_bigfloat);
623 #else 635 #else
624 ABORT (); 636 ABORT ();
625 #endif /* HAVE_BIGFLOAT */ 637 #endif /* HAVE_BIGFLOAT */
626 } 638 }
627 case BIGFLOAT_T: 639 case BIGFLOAT_T: