Correct floordiv() to cope with implementation-defined division.

Irrelevant once we get to C++11 (so we can revert this in 5.7), but
division's rounding direction is implementation defined when either
operand is negative [0].  The prior code assumed C++11's truncation
(a.k.a. round towards zero), but rounding may be downwards instead.

[0] http://en.cppreference.com/w/cpp/language/operator_arithmetic#Multiplicative_operators

Change-Id: I2b6b27e1cf629def48b25433e81b9ed8230d8795
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
bb10
Edward Welbourne 2016-01-06 14:40:50 +01:00
parent eef7725775
commit cd9625fc3c
1 changed files with 13 additions and 2 deletions

View File

@ -90,14 +90,25 @@ static inline QDate fixedDate(int y, int m, int d)
return result;
}
/*
Until C++11, rounding direction is implementation-defined.
For negative operands, implementations may chose to round down instead of
towards zero (truncation). We only actually care about the case a < 0, as all
uses of floordiv have b > 0. In this case, if rounding is down we have a % b
>= 0 and simple division works fine; but a % b = a - (a / b) * b always, so
rounding towards zero gives a % b <= 0; when < 0, we need to adjust.
Once we assume C++11, we can safely test a < 0 instead of a % b < 0.
*/
static inline qint64 floordiv(qint64 a, int b)
{
return (a - (a < 0 ? b-1 : 0)) / b;
return (a - (a % b < 0 ? b - 1 : 0)) / b;
}
static inline int floordiv(int a, int b)
{
return (a - (a < 0 ? b-1 : 0)) / b;
return (a - (a % b < 0 ? b - 1 : 0)) / b;
}
static inline qint64 julianDayFromDate(int year, int month, int day)