floor(), floorf(), and floorl(): Fix logic error. Was not correctly handling negative integral value.

This commit is contained in:
Gregory Nutt 2016-08-11 18:21:29 -06:00
parent 155055d564
commit 6e5010e0d0
3 changed files with 55 additions and 12 deletions

View File

@ -41,12 +41,26 @@
#ifdef CONFIG_HAVE_DOUBLE #ifdef CONFIG_HAVE_DOUBLE
double floor(double x) double floor(double x)
{ {
modf(x, &x); double modx;
if (x < 0.0)
/* modf() will return the integer part of X. The return value of floor
* differs for non-integer, negative values.
*
* x modf floor
* ---- ----- -----
* 2.0 2.0 2.0
* 2.4 2.0 2.0
* 2.9 2.0 2.0
* -2.7 -2.0 -3.0
* -2.0 -2.0 -2.0
*/
(void)modf(x, &modx);
if (x < 0.0 && x < modx)
{ {
x -= 1.0; modx -= 1.0;
} }
return x; return modx;
} }
#endif #endif

View File

@ -37,11 +37,25 @@
float floorf(float x) float floorf(float x)
{ {
modff(x, &x); float modx;
if (x < 0.0F)
/* modf() will return the integer part of X. The return value of floor
* differs for non-integer, negative values.
*
* x modff floor
* ---- ----- -----
* 2.0 2.0 2.0
* 2.4 2.0 2.0
* 2.9 2.0 2.0
* -2.7 -2.0 -3.0
* -2.0 -2.0 -2.0
*/
(void)modff(x, &modx);
if (x < 0.0F && x < modx)
{ {
x -= 1.0F; modx -= 1.0F;
} }
return x; return modx;
} }

View File

@ -41,12 +41,27 @@
#ifdef CONFIG_HAVE_LONG_DOUBLE #ifdef CONFIG_HAVE_LONG_DOUBLE
long double floorl(long double x) long double floorl(long double x)
{ {
modfl(x, &x); long double modx;
if (x < 0.0)
/* modf() will return the integer part of X. The return value of floor
* differs for non-integer, negative values.
*
* x modfl floor
* ---- ----- -----
* 2.0 2.0 2.0
* 2.4 2.0 2.0
* 2.9 2.0 2.0
* -2.7 -2.0 -3.0
* -2.0 -2.0 -2.0
*/
(void)modfl(x, &modx);
if (x < 0.0 && x < modx)
{ {
x -= 1.0; modx -= 1.0;
} }
return x; return modx;
} }
#endif #endif