diff --git a/src/lisp/e_acosh.c b/src/lisp/e_acosh.c index fb248d544d309076f7235afdac6e0c25a720d0fe..86e43f967a216c24bdecc99306f136dd4c559db2 100644 --- a/src/lisp/e_acosh.c +++ b/src/lisp/e_acosh.c @@ -50,10 +50,16 @@ ln2 = 6.93147180559945286227e-01; /* 0x3FE62E42, 0xFEFA39EF */ ux.d = x; hx = ux.i[HIWORD]; if(hx<0x3ff00000) { /* x < 1 */ - return (x-x)/(x-x); + return fdlibm_setexception(x, FDLIBM_INVALID); } else if(hx >=0x41b00000) { /* x > 2**28 */ if(hx >=0x7ff00000) { /* x is inf of NaN */ - return x+x; + if ((hx == 0x7ff00000) && (ux.i[LOWORD] == 0)) { + /* Overflow if x is +inf. */ + return fdlibm_setexception(x, FDLIBM_OVERFLOW); + } else { + /* Invalid if x is NaN */ + return fdlibm_setexception(x, FDLIBM_INVALID); + } } else return __ieee754_log(x)+ln2; /* acosh(huge)=log(2x) */ } else if(((hx-0x3ff00000)|ux.i[LOWORD])==0) { diff --git a/tests/trig.lisp b/tests/trig.lisp index 18c919908e191a5a0c47c3aec3d2d0d3fede1b99..62ac377d47e7e8d736537775dcfbaafc3be58d16 100644 --- a/tests/trig.lisp +++ b/tests/trig.lisp @@ -802,46 +802,61 @@ (define-test cosh.exceptions (:tag :fdlibm) (assert-error 'floating-point-overflow - (cosh 1000d0)) + (kernel:%cosh 1000d0)) (assert-error 'floating-point-overflow - (cosh -1000d0)) + (kernel:%cosh -1000d0)) (assert-error 'floating-point-invalid-operation - (cosh *nan*)) + (kernel:%cosh *nan*)) ;; Same, but with overflow's masked (kernel::with-float-traps-masked (:overflow) (assert-equal ext:double-float-positive-infinity - (cosh 1000d0)) + (kernel:%cosh 1000d0)) (assert-equal ext:double-float-positive-infinity - (cosh -1000d0)) + (kernel:%cosh -1000d0)) (assert-equal ext:double-float-positive-infinity - (cosh ext:double-float-positive-infinity)) + (kernel:%cosh ext:double-float-positive-infinity)) (assert-equal ext:double-float-positive-infinity - (cosh ext:double-float-negative-infinity))) + (kernel:%cosh ext:double-float-negative-infinity))) ;; Test NaN (kernel::with-float-traps-masked (:invalid) - (assert-true (ext:float-nan-p (cosh *nan*))))) + (assert-true (ext:float-nan-p (kernel:%cosh *nan*))))) -(define-test sinh.overflow +(define-test sinh.exceptions (:tag :fdlibm) (assert-error 'floating-point-overflow - (sinh 1000d0)) + (kernel:%sinh 1000d0)) (assert-error 'floating-point-overflow - (sinh -1000d0)) + (kernel:%sinh -1000d0)) (assert-error 'floating-point-invalid-operation - (sinh *nan*)) + (kernel:%sinh *nan*)) ;; Same, but with overflow's masked (kernel::with-float-traps-masked (:overflow) (assert-equal ext:double-float-positive-infinity - (sinh 1000d0)) + (kernel:%sinh 1000d0)) (assert-equal ext:double-float-negative-infinity - (sinh -1000d0)) + (kernel:%sinh -1000d0)) (assert-equal ext:double-float-positive-infinity - (sinh ext:double-float-positive-infinity)) + (kernel:%sinh ext:double-float-positive-infinity)) (assert-equal ext:double-float-negative-infinity - (sinh ext:double-float-negative-infinity))) + (kernel:%sinh ext:double-float-negative-infinity))) ;; Test NaN (kernel::with-float-traps-masked (:invalid) - (assert-true (ext:float-nan-p (sinh *nan*))))) + (assert-true (ext:float-nan-p (kernel:%sinh *nan*))))) +(define-test tanh.exceptions + (:tag :fdlibm) + (assert-true (ext:float-nan-p (kernel:%tanh *nan*)))) +(define-test acosh.exceptions + (:tag :fdlibm) + (assert-error 'floating-point-overflow + (kernel:%acosh ext:double-float-positive-infinity)) + (assert-error 'floating-point-invalid-operation + (kernel:%acosh 0d0)) + (kernel::with-float-traps-masked (:overflow) + (assert-equal ext:double-float-positive-infinity + (kernel:%acosh ext:double-float-positive-infinity))) + (kernel::with-float-traps-masked (:invalid) + (assert-true (ext:float-nan-p (kernel:%acosh 0d0))))) +