From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 2181) id BACCC3857C50; Tue, 12 Dec 2023 22:46:22 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org BACCC3857C50 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1702421182; bh=U9nXBWJTC05mtzNGH1rEeDe+CCQdgqrE7GfoZPM3VNk=; h=From:To:Subject:Date:From; b=WO3gKF95yn7bfpAV40PNYPUg6EB+ZMl5tIuktmuQoTMh3k/SQb4pPZSPQvxzIyCi9 lyioll00wtSPhPyQyAMfF/YH5Tk1E0j2Kx+KiWCoKrAZug9IbYpgRjV6nrv2+IVQI6 h7rdbsWvBqgDvCV+UdKC6tQ5QhP8ffx7/gqnsMt4= MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset="utf-8" From: Jonathan Wakely To: gcc-cvs@gcc.gnu.org, libstdc++-cvs@gcc.gnu.org Subject: [gcc r14-6468] libstdc++: Fix std::format output of %C for negative years X-Act-Checkin: gcc X-Git-Author: Jonathan Wakely X-Git-Refname: refs/heads/master X-Git-Oldrev: 988dd6384c88a110952833dfe7c8344b9af95fa4 X-Git-Newrev: a01462ae8bafa86e7df47a252917ba6899d587cf Message-Id: <20231212224622.BACCC3857C50@sourceware.org> Date: Tue, 12 Dec 2023 22:46:22 +0000 (GMT) List-Id: https://gcc.gnu.org/g:a01462ae8bafa86e7df47a252917ba6899d587cf commit r14-6468-ga01462ae8bafa86e7df47a252917ba6899d587cf Author: Jonathan Wakely Date: Mon Dec 11 15:33:59 2023 +0000 libstdc++: Fix std::format output of %C for negative years During discussion of LWG 4022 I noticed that we do not correctly implement floored division for the century. We were just truncating towards zero, rather than applying the floor function. For negative values that rounds the wrong way. libstdc++-v3/ChangeLog: * include/bits/chrono_io.h (__formatter_chrono::_M_C_y_Y): Fix rounding for negative centuries. * testsuite/std/time/year/io.cc: Check %C for negative years. Diff: --- libstdc++-v3/include/bits/chrono_io.h | 9 +++++++-- libstdc++-v3/testsuite/std/time/year/io.cc | 7 +++++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/libstdc++-v3/include/bits/chrono_io.h b/libstdc++-v3/include/bits/chrono_io.h index 16e8fc58dff..b63b8592eba 100644 --- a/libstdc++-v3/include/bits/chrono_io.h +++ b/libstdc++-v3/include/bits/chrono_io.h @@ -820,9 +820,14 @@ namespace __format if (__conv == 'Y' || __conv == 'C') { - if (__is_neg) - __s.assign(1, _S_plus_minus[1]); int __ci = __yi / 100; + if (__is_neg) [[unlikely]] + { + __s.assign(1, _S_plus_minus[1]); + // For floored division -123//100 is -2 and -100//100 is -1 + if ((__ci * 100) != __yi) + ++__ci; + } if (__ci >= 100) [[unlikely]] { __s += std::format(_S_empty_spec, __ci / 100); diff --git a/libstdc++-v3/testsuite/std/time/year/io.cc b/libstdc++-v3/testsuite/std/time/year/io.cc index 6157afae253..a6683ae20df 100644 --- a/libstdc++-v3/testsuite/std/time/year/io.cc +++ b/libstdc++-v3/testsuite/std/time/year/io.cc @@ -43,8 +43,11 @@ test_format() s = std::format("{}", --year::min()); // formatted via ostream VERIFY( s == "-32768 is not a valid year" ); - s = std::format("{:%y} {:%y}", 1976y, -1976y); - VERIFY( s == "76 76" ); // LWG 3831 + s = std::format("{:%C %y} {:%C %y}", 1976y, -1976y); + VERIFY( s == "19 76 -20 76" ); // LWG 3831 + + s = std::format("{:%C %y} {:%C %y} {:%C %y}", -9y, -900y, -555y); + VERIFY( s == "-01 09 -09 00 -06 55" ); // LWG 4022 s = std::format("{0:%EC}{0:%Ey} = {0:%EY}", 1642y); VERIFY( s == "1642 = 1642" );