summaryrefslogtreecommitdiff log msg author committer range
path: root/src
diff options
 context: 12345678910152025303540 space: includeignore mode: unifiedssdiffstat only
author committer Szabolcs Nagy 2013-08-15 15:13:24 +0000 Szabolcs Nagy 2013-08-15 15:13:24 +0000 c221af951693d526d3ae946f7e708af8e7a9bf85 (patch) 0d18e9fdd8cf637d98c9726ff5947d6d8b41f851 /src 411efb3bc61298b81456d0fdab39518d983a9681 (diff) musl-c221af951693d526d3ae946f7e708af8e7a9bf85.tar.gz
math: fix pow(x,-1) to raise underflow properly
if FLT_EVAL_METHOD!=0 check if (double)(1/x) is subnormal and not a power of 2 (if 1/x is power of 2 then either it is exact or the long double to double rounding already raised inexact and underflow)
Diffstat (limited to 'src')
-rw-r--r--src/math/pow.c16
1 files changed, 14 insertions, 2 deletions
 diff --git a/src/math/pow.c b/src/math/pow.cindex ac3abc0f..82f684bd 100644--- a/src/math/pow.c+++ b/src/math/pow.c@@ -146,8 +146,20 @@ double pow(double x, double y) else if ((ix|lx) != 0) /* (|x|<1)**+-inf = 0,inf if x!=0 */ return hy >= 0 ? 0.0 : -y; }- if (iy == 0x3ff00000) /* y is +-1 */- return hy >= 0 ? x : 1.0/x;+ if (iy == 0x3ff00000) { /* y is +-1 */+ if (hy >= 0)+ return x;+ y = 1/x;+#if FLT_EVAL_METHOD!=0+ {+ union {double f; uint64_t i;} u = {y};+ uint64_t i = u.i & -1ULL/2;+ if (i>>52 == 0 && (i&(i-1)))+ FORCE_EVAL((float)y);+ }+#endif+ return y;+ } if (hy == 0x40000000) /* y is 2 */ return x*x; if (hy == 0x3fe00000) { /* y is 0.5 */