2007-10-12 Bruno Haible <bruno@clisp.org>
+ * lib/floor.c (FUNC): Avoid rounding errors for values near a power
+ of 2.
+ * tests/test-floorf2.c: New file.
+ * modules/floorf-tests: (Files, Depends-on, Makefile.am): Add new test.
+
* tests/test-floorf1.c: Renamed from tests/test-floorf.c.
* modules/floorf-tests: Update.
volatile DOUBLE y = x;
volatile DOUBLE z = y;
- /* Round to the next integer (nearest or up or down, doesn't matter). */
if (z > L_(0.0))
{
- z += TWO_MANT_DIG;
- z -= TWO_MANT_DIG;
+ /* Avoid rounding errors for values near 2^k, where k >= MANT_DIG-1. */
+ if (z < TWO_MANT_DIG)
+ {
+ /* Round to the next integer (nearest or up or down, doesn't matter). */
+ z += TWO_MANT_DIG;
+ z -= TWO_MANT_DIG;
+ /* Enforce rounding down. */
+ if (z > y)
+ z -= L_(1.0);
+ }
}
else if (z < L_(0.0))
{
- z -= TWO_MANT_DIG;
- z += TWO_MANT_DIG;
+ /* Avoid rounding errors for values near -2^k, where k >= MANT_DIG-1. */
+ if (z > - TWO_MANT_DIG)
+ {
+ /* Round to the next integer (nearest or up or down, doesn't matter). */
+ z -= TWO_MANT_DIG;
+ z += TWO_MANT_DIG;
+ /* Enforce rounding down. */
+ if (z > y)
+ z -= L_(1.0);
+ }
}
- /* Enforce rounding down. */
- if (z > y)
- z -= L_(1.0);
-
return z;
}
Files:
tests/test-floorf1.c
+tests/test-floorf2.c
Depends-on:
+float
+isnanf-nolibm
+stdbool
+stdint
configure.ac:
Makefile.am:
-TESTS += test-floorf1
-check_PROGRAMS += test-floorf1
+TESTS += test-floorf1 test-floorf2
+check_PROGRAMS += test-floorf1 test-floorf2
test_floorf1_LDADD = $(LDADD) @FLOORF_LIBM@
+test_floorf2_LDADD = $(LDADD) @FLOORF_LIBM@
License:
LGPL