X-Git-Url: http://erislabs.net/gitweb/?a=blobdiff_plain;f=lib%2Fceil.c;h=b5a0316cf1798e2a773da99103f04b696d3681ed;hb=4f9d80b9d8004f0fcedf3525e268abaa24b8b4a9;hp=169c68fe5e09dac269e1575f0381ccf48c00a95a;hpb=d9cd580560f5ba3bd4c669d78321eb9947f4d568;p=gnulib.git diff --git a/lib/ceil.c b/lib/ceil.c index 169c68fe5..b5a0316cf 100644 --- a/lib/ceil.c +++ b/lib/ceil.c @@ -63,20 +63,31 @@ FUNC (DOUBLE x) 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 up. */ + 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 up. */ + if (z < y) + z += L_(1.0); + } } - /* Enforce rounding up. */ - if (z < y) - z += L_(1.0); - return z; }