From 80a526861fb16e72046a61a01b77f9451b5dd2a1 Mon Sep 17 00:00:00 2001 From: Ell Date: Thu, 5 Oct 2017 17:35:10 -0400 Subject: [PATCH] Bug 788461 - Selection with a Fixed size is created with an ... ... off-by one size in special cases The last commit wasn't drastic enough. We changed SIGNED_ROUND() to use RINT(), which, in turn, may use rint(). However, rint() effectively breaks ties to even, so that we get stuff like 'rint (1.5) - rint (0.5) == 2.0 - 0.0 == 2.0'. This can't be good--it's entirely possible that we're bitten by this in other cases without noticing. Avoid rint() entirely in RINT(), and always use 'floor (x) + 0.5' instead, which always breaks ties up. Hopefully, this doesn't break anything else... --- libgimpmath/gimpmath.h | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/libgimpmath/gimpmath.h b/libgimpmath/gimpmath.h index 5925004130..b7f5d6a81a 100644 --- a/libgimpmath/gimpmath.h +++ b/libgimpmath/gimpmath.h @@ -64,7 +64,13 @@ G_BEGIN_DECLS * This macro rounds its argument @x to an integer value in floating * point format. Use RINT() instead of rint(). **/ -#ifdef HAVE_RINT +#if defined (HAVE_RINT) && 0 +/* note: rint() depends on the current floating-point rounding mode. when the + * rounding mode is FE_TONEAREST, it, in parctice, breaks ties to even. this + * is different from 'floor (x + 0.5)', which breaks ties up. in other words + * 'rint (2.5) == 2.0', while 'floor (2.5 + 0.5) == 3.0'. this is asking for + * trouble, so let's just use the latter. + */ #define RINT(x) rint(x) #else #define RINT(x) floor ((x) + 0.5)