Skip to content
Snippets Groups Projects
Commit a31150c5 authored by Raymond Toy's avatar Raymond Toy
Browse files

Use setexception to raise the inexact exception for tan.

parent 71bdff74
No related branches found
No related tags found
No related merge requests found
......@@ -78,31 +78,34 @@ __kernel_tan(double x, double y, int iy) {
hx = ux.i[HIWORD]; /* high word of x */
ix = hx & 0x7fffffff; /* high word of |x| */
if (ix < 0x3e300000) { /* x < 2**-28 */
if ((int) x == 0) { /* generate inexact */
if (((ix | ux.i[LOWORD]) | (iy + 1)) == 0)
return one / fabs(x);
else {
if (iy == 1)
return x;
else { /* compute -1 / (x+y) carefully */
double a, t;
/* return x inexact except 0 */
if (x != 0) {
fdlibm_setexception(x, FDLIBM_INEXACT);
}
z = w = x + y;
uz.d = z;
uz.i[LOWORD] = 0;
z = ux.d;
if (((ix | ux.i[LOWORD]) | (iy + 1)) == 0)
return one / fabs(x);
else {
if (iy == 1)
return x;
else { /* compute -1 / (x+y) carefully */
double a, t;
z = w = x + y;
uz.d = z;
uz.i[LOWORD] = 0;
z = ux.d;
v = y - (z - x);
t = a = -one / w;
uz.d = t;
uz.i[LOWORD] = 0;
t = uz.d;
v = y - (z - x);
t = a = -one / w;
uz.d = t;
uz.i[LOWORD] = 0;
t = uz.d;
s = one + t * z;
return t + a * (s + t * v);
}
}
s = one + t * z;
return t + a * (s + t * v);
}
}
}
if (ix >= 0x3FE59428) { /* |x| >= 0.6744 */
if (hx < 0) {
......
......@@ -638,3 +638,18 @@
(assert-error 'floating-point-inexact
(kernel:%sin x)))))
(define-test %tan.exceptions
(:tag :fdlibm)
;; tan(x) = x for |x| < 2^-28. Signal inexact unless x = 0
(let ((x (scale-float 1d0 -29))
(x0 0d0))
(with-inexact-exception-enabled
;; This must not throw an inexact exception because the result
;; is exact when the arg is 0.
(assert-eql 0d0 (kernel:%tan x0)))
(with-inexact-exception-enabled
;; This must throw an inexact exception for non-zero x even
;; though the result is exactly x.
(assert-error 'floating-point-inexact
(kernel:%tan x)))))
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment