Fix nexttoward bugs (bugs 2550, 2570).

This commit is contained in:
Joseph Myers 2012-05-01 15:37:43 +00:00
parent 412bd96612
commit 7cb029ee6e
12 changed files with 121 additions and 82 deletions

View File

@ -1,3 +1,24 @@
2012-05-01 Joseph Myers <joseph@codesourcery.com>
[BZ #2550]
[BZ #2570]
* math/s_nexttowardf.c (__nexttowardf): Use floating-point
comparisons to determine direction to adjust input.
* sysdeps/i386/fpu/s_nexttoward.c (__nexttoward): Likewise.
* sysdeps/i386/fpu/s_nexttowardf.c(__nexttowardf): Likewise.
* sysdeps/ieee754/ldbl-128/s_nexttoward.c (__nexttoward):
Likewise.
* sysdeps/ieee754/ldbl-128/s_nexttowardf.c (__nexttowardf):
Likewise.
* sysdeps/ieee754/ldbl-128ibm/s_nexttowardf.c (__nexttowardf):
Likewise.
* sysdeps/ieee754/ldbl-96/s_nexttoward.c (__nexttoward): Likewise.
* sysdeps/ieee754/ldbl-96/s_nexttowardf.c (__nexttowardf):
Likewise.
* sysdeps/ieee754/ldbl-opt/s_nexttowardfd.c (__nldbl_nexttowardf):
Likewise.
* math/libm-test.inc (nexttoward_test): Add more tests.
2012-05-01 Andreas Schwab <schwab@linux-m68k.org> 2012-05-01 Andreas Schwab <schwab@linux-m68k.org>
[BZ #14040] [BZ #14040]

29
NEWS
View File

@ -9,20 +9,21 @@ Version 2.16
* The following bugs are resolved with this release: * The following bugs are resolved with this release:
174, 350, 369, 411, 706, 887, 2074, 2541, 2547, 2548, 2551, 2552, 2553, 174, 350, 369, 411, 706, 887, 2074, 2541, 2547, 2548, 2550, 2551, 2552,
2554, 2562, 2563, 2565, 2566, 2576, 2636, 2678, 3335, 3768, 3866, 3868, 2553, 2554, 2562, 2563, 2565, 2566, 2570, 2576, 2636, 2678, 3335, 3768,
3976, 3992, 4026, 4108, 4596, 4822, 5077, 5461, 5805, 5993, 6471, 6486, 3866, 3868, 3976, 3992, 4026, 4108, 4596, 4822, 5077, 5461, 5805, 5993,
6578, 6649, 6730, 6770, 6794, 6884, 6890, 6894, 6895, 6907, 6911, 7064, 6471, 6486, 6578, 6649, 6730, 6770, 6794, 6884, 6890, 6894, 6895, 6907,
9739, 9902, 10110, 10135, 10140, 10153, 10210, 10254, 10346, 10545, 10716, 6911, 7064, 9739, 9902, 10110, 10135, 10140, 10153, 10210, 10254, 10346,
11174, 11322, 11365, 11451, 11494, 11521, 11959, 12047, 12340, 13058, 10545, 10716, 11174, 11322, 11365, 11451, 11494, 11521, 11959, 12047,
13525, 13526, 13527, 13528, 13529, 13530, 13531, 13532, 13533, 13547, 12340, 13058, 13525, 13526, 13527, 13528, 13529, 13530, 13531, 13532,
13551, 13552, 13553, 13555, 13559, 13566, 13583, 13592, 13618, 13637, 13533, 13547, 13551, 13552, 13553, 13555, 13559, 13566, 13583, 13592,
13656, 13658, 13673, 13691, 13695, 13704, 13705, 13706, 13726, 13738, 13618, 13637, 13656, 13658, 13673, 13691, 13695, 13704, 13705, 13706,
13739, 13758, 13760, 13761, 13786, 13792, 13806, 13824, 13840, 13841, 13726, 13738, 13739, 13758, 13760, 13761, 13786, 13792, 13806, 13824,
13844, 13846, 13851, 13852, 13854, 13871, 13872, 13873, 13879, 13883, 13840, 13841, 13844, 13846, 13851, 13852, 13854, 13871, 13872, 13873,
13886, 13892, 13895, 13908, 13910, 13911, 13912, 13913, 13915, 13916, 13879, 13883, 13886, 13892, 13895, 13908, 13910, 13911, 13912, 13913,
13917, 13918, 13919, 13920, 13921, 13924, 13926, 13927, 13928, 13938, 13915, 13916, 13917, 13918, 13919, 13920, 13921, 13924, 13926, 13927,
13941, 13942, 13963, 13967, 13970, 13973, 14027, 14033, 14034, 14040 13928, 13938, 13941, 13942, 13963, 13967, 13970, 13973, 14027, 14033,
14034, 14040
* ISO C11 support: * ISO C11 support:

View File

@ -5743,8 +5743,73 @@ nexttoward_test (void)
TEST_ff_f (nexttoward, 1.1L, nan_value, nan_value); TEST_ff_f (nexttoward, 1.1L, nan_value, nan_value);
TEST_ff_f (nexttoward, nan_value, nan_value, nan_value); TEST_ff_f (nexttoward, nan_value, nan_value, nan_value);
/* XXX We need the hexadecimal FP number representation here for further #ifdef TEST_FLOAT
tests. */ TEST_ff_f (nexttoward, 1.0, 1.1L, 0x1.000002p0);
TEST_ff_f (nexttoward, 1.0, LDBL_MAX, 0x1.000002p0);
TEST_ff_f (nexttoward, 1.0, 0x1.0000000000001p0, 0x1.000002p0);
TEST_ff_f (nexttoward, 1.0, 0.9L, 0x0.ffffffp0);
TEST_ff_f (nexttoward, 1.0, -LDBL_MAX, 0x0.ffffffp0);
TEST_ff_f (nexttoward, 1.0, 0x0.fffffffffffff8p0, 0x0.ffffffp0);
TEST_ff_f (nexttoward, -1.0, -1.1L, -0x1.000002p0);
TEST_ff_f (nexttoward, -1.0, -LDBL_MAX, -0x1.000002p0);
TEST_ff_f (nexttoward, -1.0, -0x1.0000000000001p0, -0x1.000002p0);
TEST_ff_f (nexttoward, -1.0, -0.9L, -0x0.ffffffp0);
TEST_ff_f (nexttoward, -1.0, LDBL_MAX, -0x0.ffffffp0);
TEST_ff_f (nexttoward, -1.0, -0x0.fffffffffffff8p0, -0x0.ffffffp0);
TEST_ff_f (nexttoward, -0x1.3p-145, -0xap-148L, -0x1.4p-145);
# if LDBL_MANT_DIG >= 64
TEST_ff_f (nexttoward, 1.0, 0x1.000000000000002p0L, 0x1.000002p0);
TEST_ff_f (nexttoward, 1.0, 0x0.ffffffffffffffffp0L, 0x0.ffffffp0);
TEST_ff_f (nexttoward, -1.0, -0x1.000000000000002p0L, -0x1.000002p0);
TEST_ff_f (nexttoward, -1.0, -0x0.ffffffffffffffffp0L, -0x0.ffffffp0);
# endif
# if LDBL_MANT_DIG >= 106
TEST_ff_f (nexttoward, 1.0, 0x1.000000000000000000000000008p0L, 0x1.000002p0);
TEST_ff_f (nexttoward, 1.0, 0x0.ffffffffffffffffffffffffffcp0L, 0x0.ffffffp0);
TEST_ff_f (nexttoward, -1.0, -0x1.000000000000000000000000008p0L, -0x1.000002p0);
TEST_ff_f (nexttoward, -1.0, -0x0.ffffffffffffffffffffffffffcp0L, -0x0.ffffffp0);
# endif
# if LDBL_MANT_DIG >= 113
TEST_ff_f (nexttoward, 1.0, 0x1.0000000000000000000000000001p0L, 0x1.000002p0);
TEST_ff_f (nexttoward, 1.0, 0x0.ffffffffffffffffffffffffffff8p0L, 0x0.ffffffp0);
TEST_ff_f (nexttoward, -1.0, -0x1.0000000000000000000000000001p0L, -0x1.000002p0);
TEST_ff_f (nexttoward, -1.0, -0x0.ffffffffffffffffffffffffffff8p0L, -0x0.ffffffp0);
# endif
#endif
#ifdef TEST_DOUBLE
TEST_ff_f (nexttoward, 1.0, 1.1L, 0x1.0000000000001p0);
TEST_ff_f (nexttoward, 1.0, LDBL_MAX, 0x1.0000000000001p0);
TEST_ff_f (nexttoward, 1.0, 0x1.0000000000001p0, 0x1.0000000000001p0);
TEST_ff_f (nexttoward, 1.0, 0.9L, 0x0.fffffffffffff8p0);
TEST_ff_f (nexttoward, 1.0, -LDBL_MAX, 0x0.fffffffffffff8p0);
TEST_ff_f (nexttoward, 1.0, 0x0.fffffffffffff8p0, 0x0.fffffffffffff8p0);
TEST_ff_f (nexttoward, -1.0, -1.1L, -0x1.0000000000001p0);
TEST_ff_f (nexttoward, -1.0, -LDBL_MAX, -0x1.0000000000001p0);
TEST_ff_f (nexttoward, -1.0, -0x1.0000000000001p0, -0x1.0000000000001p0);
TEST_ff_f (nexttoward, -1.0, -0.9L, -0x0.fffffffffffff8p0);
TEST_ff_f (nexttoward, -1.0, LDBL_MAX, -0x0.fffffffffffff8p0);
TEST_ff_f (nexttoward, -1.0, -0x0.fffffffffffff8p0, -0x0.fffffffffffff8p0);
TEST_ff_f (nexttoward, -1.0, -0x8.00346dc5d6388p-3L, -0x1.0000000000001p0);
TEST_ff_f (nexttoward, 0x1p-1074, 0x1p-1073L, 0x1p-1073);
# if LDBL_MANT_DIG >= 64
TEST_ff_f (nexttoward, 1.0, 0x1.000000000000002p0L, 0x1.0000000000001p0);
TEST_ff_f (nexttoward, 1.0, 0x0.ffffffffffffffffp0L, 0x0.fffffffffffff8p0);
TEST_ff_f (nexttoward, -1.0, -0x1.000000000000002p0L, -0x1.0000000000001p0);
TEST_ff_f (nexttoward, -1.0, -0x0.ffffffffffffffffp0L, -0x0.fffffffffffff8p0);
# endif
# if LDBL_MANT_DIG >= 106
TEST_ff_f (nexttoward, 1.0, 0x1.000000000000000000000000008p0L, 0x1.0000000000001p0);
TEST_ff_f (nexttoward, 1.0, 0x0.ffffffffffffffffffffffffffcp0L, 0x0.fffffffffffff8p0);
TEST_ff_f (nexttoward, -1.0, -0x1.000000000000000000000000008p0L, -0x1.0000000000001p0);
TEST_ff_f (nexttoward, -1.0, -0x0.ffffffffffffffffffffffffffcp0L, -0x0.fffffffffffff8p0);
# endif
# if LDBL_MANT_DIG >= 113
TEST_ff_f (nexttoward, 1.0, 0x1.0000000000000000000000000001p0L, 0x1.0000000000001p0);
TEST_ff_f (nexttoward, 1.0, 0x0.ffffffffffffffffffffffffffff8p0L, 0x0.fffffffffffff8p0);
TEST_ff_f (nexttoward, -1.0, -0x1.0000000000000000000000000001p0L, -0x1.0000000000001p0);
TEST_ff_f (nexttoward, -1.0, -0x0.ffffffffffffffffffffffffffff8p0L, -0x0.fffffffffffff8p0);
# endif
#endif
END (nexttoward); END (nexttoward);
} }

View File

@ -47,16 +47,12 @@ float __nexttowardf(float x, long double y)
return x; return x;
} }
if(hx>=0) { /* x > 0 */ if(hx>=0) { /* x > 0 */
if(hy<0||(ix>>23)>(iy>>20)-0x380 if(x > y) /* x -= ulp */
|| ((ix>>23)==(iy>>20)-0x380
&& (ix&0x7fffff)>(((hy<<3)|(ly>>29))&0x7fffff))) /* x > y, x -= ulp */
hx -= 1; hx -= 1;
else /* x < y, x += ulp */ else /* x < y, x += ulp */
hx += 1; hx += 1;
} else { /* x < 0 */ } else { /* x < 0 */
if(hy>=0||(ix>>23)>(iy>>20)-0x380 if(x < y) /* x -= ulp */
|| ((ix>>23)==(iy>>20)-0x380
&& (ix&0x7fffff)>(((hy<<3)|(ly>>29))&0x7fffff))) /* x < y, x -= ulp */
hx -= 1; hx -= 1;
else /* x > y, x += ulp */ else /* x > y, x += ulp */
hx += 1; hx += 1;

View File

@ -55,11 +55,7 @@ double __nexttoward(double x, long double y)
return x; return x;
} }
if(hx>=0) { /* x > 0 */ if(hx>=0) { /* x > 0 */
if (esy>=0x8000||((ix>>20)&0x7ff)>iy-0x3c00 if (x > y) { /* x -= ulp */
|| (((ix>>20)&0x7ff)==iy-0x3c00
&& (((hx<<11)|(lx>>21))>(hy&0x7fffffff)
|| (((hx<<11)|(lx>>21))==(hy&0x7fffffff)
&& (lx<<11)>ly)))) { /* x > y, x -= ulp */
if(lx==0) hx -= 1; if(lx==0) hx -= 1;
lx -= 1; lx -= 1;
} else { /* x < y, x += ulp */ } else { /* x < y, x += ulp */
@ -67,11 +63,7 @@ double __nexttoward(double x, long double y)
if(lx==0) hx += 1; if(lx==0) hx += 1;
} }
} else { /* x < 0 */ } else { /* x < 0 */
if (esy<0x8000||((ix>>20)&0x7ff)>iy-0x3c00 if (x < y) { /* x -= ulp */
|| (((ix>>20)&0x7ff)==iy-0x3c00
&& (((hx<<11)|(lx>>21))>(hy&0x7fffffff)
|| (((hx<<11)|(lx>>21))==(hy&0x7fffffff)
&& (lx<<11)>ly)))) {/* x < y, x -= ulp */
if(lx==0) hx -= 1; if(lx==0) hx -= 1;
lx -= 1; lx -= 1;
} else { /* x > y, x += ulp */ } else { /* x > y, x += ulp */

View File

@ -47,17 +47,13 @@ float __nexttowardf(float x, long double y)
return x; return x;
} }
if(hx>=0) { /* x > 0 */ if(hx>=0) { /* x > 0 */
if(esy>=0x8000||((ix>>23)&0xff)>iy-0x3f80 if(x > y) { /* x -= ulp */
|| (((ix>>23)&0xff)==iy-0x3f80
&& ((ix&0x7fffff)<<8)>(hy&0x7fffffff))) {/* x > y, x -= ulp */
hx -= 1; hx -= 1;
} else { /* x < y, x += ulp */ } else { /* x < y, x += ulp */
hx += 1; hx += 1;
} }
} else { /* x < 0 */ } else { /* x < 0 */
if(esy<0x8000||((ix>>23)&0xff)>iy-0x3f80 if(x < y) { /* x -= ulp */
|| (((ix>>23)&0xff)==iy-0x3f80
&& ((ix&0x7fffff)<<8)>(hy&0x7fffffff))) {/* x < y, x -= ulp */
hx -= 1; hx -= 1;
} else { /* x > y, x += ulp */ } else { /* x > y, x += ulp */
hx += 1; hx += 1;

View File

@ -55,11 +55,7 @@ double __nexttoward(double x, long double y)
return x; return x;
} }
if(hx>=0) { /* x > 0 */ if(hx>=0) { /* x > 0 */
if (hy<0||(ix>>20)>(iy>>48)-0x3c00 if (x > y) { /* x -= ulp */
|| ((ix>>20)==(iy>>48)-0x3c00
&& (((((int64_t)hx)<<28)|(lx>>4))>(hy&0x0000ffffffffffffLL)
|| (((((int64_t)hx)<<28)|(lx>>4))==(hy&0x0000ffffffffffffLL)
&& (lx&0xf)>(ly>>60))))) { /* x > y, x -= ulp */
if(lx==0) hx -= 1; if(lx==0) hx -= 1;
lx -= 1; lx -= 1;
} else { /* x < y, x += ulp */ } else { /* x < y, x += ulp */
@ -67,11 +63,7 @@ double __nexttoward(double x, long double y)
if(lx==0) hx += 1; if(lx==0) hx += 1;
} }
} else { /* x < 0 */ } else { /* x < 0 */
if (hy>=0||(ix>>20)>(iy>>48)-0x3c00 if (x < y) { /* x -= ulp */
|| ((ix>>20)==(iy>>48)-0x3c00
&& (((((int64_t)hx)<<28)|(lx>>4))>(hy&0x0000ffffffffffffLL)
|| (((((int64_t)hx)<<28)|(lx>>4))==(hy&0x0000ffffffffffffLL)
&& (lx&0xf)>(ly>>60))))) { /* x < y, x -= ulp */
if(lx==0) hx -= 1; if(lx==0) hx -= 1;
lx -= 1; lx -= 1;
} else { /* x > y, x += ulp */ } else { /* x > y, x += ulp */

View File

@ -46,17 +46,13 @@ float __nexttowardf(float x, long double y)
return x; return x;
} }
if(hx>=0) { /* x > 0 */ if(hx>=0) { /* x > 0 */
if(hy<0||(ix>>23)>(iy>>48)-0x3f80 if(x > y) { /* x -= ulp */
|| ((ix>>23)==(iy>>48)-0x3f80
&& (ix&0x7fffff)>((hy>>25)&0x7fffff))) {/* x > y, x -= ulp */
hx -= 1; hx -= 1;
} else { /* x < y, x += ulp */ } else { /* x < y, x += ulp */
hx += 1; hx += 1;
} }
} else { /* x < 0 */ } else { /* x < 0 */
if(hy>=0||(ix>>23)>(iy>>48)-0x3f80 if(x < y) { /* x < y, x -= ulp */
|| ((ix>>23)==(iy>>48)-0x3f80
&& (ix&0x7fffff)>((hy>>25)&0x7fffff))) {/* x < y, x -= ulp */
hx -= 1; hx -= 1;
} else { /* x > y, x += ulp */ } else { /* x > y, x += ulp */
hx += 1; hx += 1;

View File

@ -49,17 +49,13 @@ float __nexttowardf(float x, long double y)
return x; return x;
} }
if(hx>=0) { /* x > 0 */ if(hx>=0) { /* x > 0 */
if(hy<0||(ix>>23)>(iy>>52)-0x380 if(x > y) { /* x -= ulp */
|| ((ix>>23)==(iy>>52)-0x380
&& (ix&0x7fffff)>((hy>>29)&0x7fffff))) {/* x > y, x -= ulp */
hx -= 1; hx -= 1;
} else { /* x < y, x += ulp */ } else { /* x < y, x += ulp */
hx += 1; hx += 1;
} }
} else { /* x < 0 */ } else { /* x < 0 */
if(hy>=0||(ix>>23)>(iy>>52)-0x380 if(x < y) { /* x -= ulp */
|| ((ix>>23)==(iy>>52)-0x380
&& (ix&0x7fffff)>((hy>>29)&0x7fffff))) {/* x < y, x -= ulp */
hx -= 1; hx -= 1;
} else { /* x > y, x += ulp */ } else { /* x > y, x += ulp */
hx += 1; hx += 1;

View File

@ -52,11 +52,7 @@ double __nexttoward(double x, long double y)
return x; return x;
} }
if(hx>=0) { /* x > 0 */ if(hx>=0) { /* x > 0 */
if (esy>=0x8000||((ix>>20)&0x7ff)>iy-0x3c00 if (x > y) { /* x -= ulp */
|| (((ix>>20)&0x7ff)==iy-0x3c00
&& (((hx<<11)|(lx>>21))>(hy&0x7fffffff)
|| (((hx<<11)|(lx>>21))==(hy&0x7fffffff)
&& (lx<<11)>ly)))) { /* x > y, x -= ulp */
if(lx==0) hx -= 1; if(lx==0) hx -= 1;
lx -= 1; lx -= 1;
} else { /* x < y, x += ulp */ } else { /* x < y, x += ulp */
@ -64,11 +60,7 @@ double __nexttoward(double x, long double y)
if(lx==0) hx += 1; if(lx==0) hx += 1;
} }
} else { /* x < 0 */ } else { /* x < 0 */
if (esy<0x8000||((ix>>20)&0x7ff)>iy-0x3c00 if (x < y) { /* x -= ulp */
|| (((ix>>20)&0x7ff)==iy-0x3c00
&& (((hx<<11)|(lx>>21))>(hy&0x7fffffff)
|| (((hx<<11)|(lx>>21))==(hy&0x7fffffff)
&& (lx<<11)>ly)))) {/* x < y, x -= ulp */
if(lx==0) hx -= 1; if(lx==0) hx -= 1;
lx -= 1; lx -= 1;
} else { /* x > y, x += ulp */ } else { /* x > y, x += ulp */

View File

@ -44,17 +44,13 @@ float __nexttowardf(float x, long double y)
return x; return x;
} }
if(hx>=0) { /* x > 0 */ if(hx>=0) { /* x > 0 */
if(esy>=0x8000||((ix>>23)&0xff)>iy-0x3f80 if(x > y) { /* x -= ulp */
|| (((ix>>23)&0xff)==iy-0x3f80
&& ((ix&0x7fffff)<<8)>(hy&0x7fffffff))) {/* x > y, x -= ulp */
hx -= 1; hx -= 1;
} else { /* x < y, x += ulp */ } else { /* x < y, x += ulp */
hx += 1; hx += 1;
} }
} else { /* x < 0 */ } else { /* x < 0 */
if(esy<0x8000||((ix>>23)&0xff)>iy-0x3f80 if(x < y) { /* x -= ulp */
|| (((ix>>23)&0xff)==iy-0x3f80
&& ((ix&0x7fffff)<<8)>(hy&0x7fffffff))) {/* x < y, x -= ulp */
hx -= 1; hx -= 1;
} else { /* x > y, x += ulp */ } else { /* x > y, x += ulp */
hx += 1; hx += 1;

View File

@ -50,16 +50,12 @@ float __nldbl_nexttowardf(float x, double y)
return x; return x;
} }
if(hx>=0) { /* x > 0 */ if(hx>=0) { /* x > 0 */
if(hy<0||(ix>>23)>(iy>>20)-0x380 if(x > y) /* x -= ulp */
|| ((ix>>23)==(iy>>20)-0x380
&& (ix&0x7fffff)>(((hy<<3)|(ly>>29))&0x7fffff))) /* x > y, x -= ulp */
hx -= 1; hx -= 1;
else /* x < y, x += ulp */ else /* x < y, x += ulp */
hx += 1; hx += 1;
} else { /* x < 0 */ } else { /* x < 0 */
if(hy>=0||(ix>>23)>(iy>>20)-0x380 if(x < y) /* x -= ulp */
|| ((ix>>23)==(iy>>20)-0x380
&& (ix&0x7fffff)>(((hy<<3)|(ly>>29))&0x7fffff))) /* x < y, x -= ulp */
hx -= 1; hx -= 1;
else /* x > y, x += ulp */ else /* x > y, x += ulp */
hx += 1; hx += 1;