From: Frank Tang Date: Thu, 19 Jan 2023 00:39:17 +0000 (-0800) Subject: ICU-22058 make pointer argument in floorDivide optional X-Git-Tag: cldr/2023-02-02~4 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=bb0e745e25c99cc57055caf45c81b95ef63b25d4;p=icu ICU-22058 make pointer argument in floorDivide optional Check the third argument and not set if it is a nullptr --- diff --git a/icu4c/source/i18n/gregoimp.cpp b/icu4c/source/i18n/gregoimp.cpp index f862cd1d831..31b5aeed835 100644 --- a/icu4c/source/i18n/gregoimp.cpp +++ b/icu4c/source/i18n/gregoimp.cpp @@ -37,11 +37,13 @@ int32_t ClockMath::floorDivide(double numerator, int32_t denominator, // For an integer n and representable ⌊x/n⌋, ⌊RN(x/n)⌋=⌊x/n⌋, where RN is // rounding to nearest. double quotient = uprv_floor(numerator / denominator); - // For doubles x and n, where n is an integer and ⌊x+n⌋ < 2³¹, the - // expression `(int32_t) (x + n)` evaluated with rounding to nearest - // differs from ⌊x+n⌋ if 0 < ⌈x⌉−x ≪ x+n, as `x + n` is rounded up to - // n+⌈x⌉ = ⌊x+n⌋ + 1. Rewriting it as ⌊x⌋+n makes the addition exact. - *remainder = (int32_t) (uprv_floor(numerator) - (quotient * denominator)); + if (remainder != nullptr) { + // For doubles x and n, where n is an integer and ⌊x+n⌋ < 2³¹, the + // expression `(int32_t) (x + n)` evaluated with rounding to nearest + // differs from ⌊x+n⌋ if 0 < ⌈x⌉−x ≪ x+n, as `x + n` is rounded up to + // n+⌈x⌉ = ⌊x+n⌋ + 1. Rewriting it as ⌊x⌋+n makes the addition exact. + *remainder = (int32_t) (uprv_floor(numerator) - (quotient * denominator)); + } return (int32_t) quotient; } @@ -50,16 +52,16 @@ double ClockMath::floorDivide(double dividend, double divisor, // Only designed to work for positive divisors U_ASSERT(divisor > 0); double quotient = floorDivide(dividend, divisor); - *remainder = dividend - (quotient * divisor); + double r = dividend - (quotient * divisor); // N.B. For certain large dividends, on certain platforms, there // is a bug such that the quotient is off by one. If you doubt // this to be true, set a breakpoint below and run cintltst. - if (*remainder < 0 || *remainder >= divisor) { + if (r < 0 || r >= divisor) { // E.g. 6.7317038241449352e+022 / 86400000.0 is wrong on my // machine (too high by one). 4.1792057231752762e+024 / // 86400000.0 is wrong the other way (too low). double q = quotient; - quotient += (*remainder < 0) ? -1 : +1; + quotient += (r < 0) ? -1 : +1; if (q == quotient) { // For quotients > ~2^53, we won't be able to add or // subtract one, since the LSB of the mantissa will be > @@ -70,12 +72,15 @@ double ClockMath::floorDivide(double dividend, double divisor, // values give back an approximate answer rather than // crashing. For example, UDate values above a ~10^25 // might all have a time of midnight. - *remainder = 0; + r = 0; } else { - *remainder = dividend - (quotient * divisor); + r = dividend - (quotient * divisor); } } - U_ASSERT(0 <= *remainder && *remainder < divisor); + U_ASSERT(0 <= r && r < divisor); + if (remainder != nullptr) { + *remainder = r; + } return quotient; }