Skip to content

Commit be7826f

Browse files
committed
math: Use unsigned ints when checking for 64-bit float == 1.0 or 2.0
A common pattern in the math code is to want to check for equality to 1.0, but using the raw bits of the value stored in two ints. That's done with ((hi - 0x3ff00000) | lo) == 0, but 'hi' is often stored as a signed value to make checking the sign bit easier. Do the subtraction using unsigned values to avoid undefined behavior. Signed-off-by: Keith Packard <[email protected]>
1 parent 4128ea3 commit be7826f

File tree

5 files changed

+7
-7
lines changed

5 files changed

+7
-7
lines changed

newlib/libm/math/s_acos.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ acos64(__float64 x)
6565
if (ix >= 0x3ff00000) { /* |x| >= 1 */
6666
__uint32_t lx;
6767
GET_LOW_WORD(lx, x);
68-
if (((ix - 0x3ff00000) | lx) == 0) { /* |x|==1 */
68+
if ((((__uint32_t) ix - 0x3ff00000) | lx) == 0) { /* |x|==1 */
6969
if (hx > 0)
7070
return _F_64(0.0); /* acos(1) = 0 */
7171
else

newlib/libm/math/s_acosh.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ acosh64(__float64 x)
4848
return x + x;
4949
} else
5050
return log64(x) + ln2; /* acosh(huge)=log(2x) */
51-
} else if (((hx - 0x3ff00000) | lx) == 0) {
51+
} else if ((((__uint32_t) hx - 0x3ff00000) | lx) == 0) {
5252
return _F_64(0.0); /* acosh(1) = 0 */
5353
} else if (hx > 0x40000000) { /* 2**28 > x > 2 */
5454
t = x * x;

newlib/libm/math/s_asin.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ asin64(__float64 x)
7373
if (ix >= 0x3ff00000) { /* |x|>= 1 */
7474
__uint32_t lx;
7575
GET_LOW_WORD(lx, x);
76-
if (((ix - 0x3ff00000) | lx) == 0)
76+
if ((((__uint32_t) ix - 0x3ff00000) | lx) == 0)
7777
/* asin(1)=+-pi/2 with inexact */
7878
return x * pio2_hi + x * pio2_lo;
7979
return __math_invalid(x); /* asin(|x|>1) is NaN */

newlib/libm/math/s_pow.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ pow64(__float64 x, __float64 y)
118118
/* x|y==NaN return NaN unless x==1 then return 1 */
119119
if (ix > 0x7ff00000 || ((ix == 0x7ff00000) && (lx != 0)) ||
120120
iy > 0x7ff00000 || ((iy == 0x7ff00000) && (ly != 0))) {
121-
if (((hx - 0x3ff00000) | lx) == 0 && !issignaling64_inline(y))
121+
if ((((__uint32_t) hx - 0x3ff00000) | lx) == 0 && !issignaling64_inline(y))
122122
return one;
123123
else
124124
return x + y;
@@ -150,7 +150,7 @@ pow64(__float64 x, __float64 y)
150150
/* special value of y */
151151
if (ly == 0) {
152152
if (iy == 0x7ff00000) { /* y is +-inf */
153-
if (((ix - 0x3ff00000) | lx) == 0)
153+
if ((((__uint32_t) ix - 0x3ff00000) | lx) == 0)
154154
return one; /* +-1**+-inf = 1 */
155155
else if (ix >= 0x3ff00000) /* (|x|>1)**+-inf = inf,0 */
156156
return (hy >= 0) ? y : zero;
@@ -181,7 +181,7 @@ pow64(__float64 x, __float64 y)
181181
if (hy < 0)
182182
z = one / z; /* z = (1/|x|) */
183183
if (hx < 0) {
184-
if (((ix - 0x3ff00000) | yisint) == 0) {
184+
if ((((__uint32_t) ix - 0x3ff00000) | yisint) == 0) {
185185
return __math_invalid(x); /* (-1)**non-int is NaN */
186186
} else if (yisint == 1)
187187
z = -z; /* (x<0)**odd = -(|x|**odd) */

newlib/libm/math/sr_lgamma.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -256,7 +256,7 @@ __math_lgamma_r(__float64 x, int *signgamp, int *divzero)
256256
}
257257

258258
/* purge off 1 and 2 */
259-
if ((((ix - 0x3ff00000) | lx) == 0) || (((ix - 0x40000000) | lx) == 0))
259+
if (((((__uint32_t) ix - 0x3ff00000) | lx) == 0) || ((((__uint32_t) ix - 0x40000000) | lx) == 0))
260260
r = 0;
261261
/* for x < 2.0 */
262262
else if (ix < 0x40000000) {

0 commit comments

Comments
 (0)