aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJonathan Wakely <jwakely@redhat.com>2024-01-30 14:47:34 +0000
committerJonathan Wakely <redi@gcc.gnu.org>2024-09-26 21:32:01 +0100
commitee9f00606f184be37d6f9df74cc7e222157c7fee (patch)
tree2c70b549660d9983b97cb6ba2c2c83b896da4526 /gcc
parent5ad6ff2b4a0a6b7495d580d36283a7e8fd78e47d (diff)
downloadgcc-ee9f00606f184be37d6f9df74cc7e222157c7fee.zip
gcc-ee9f00606f184be37d6f9df74cc7e222157c7fee.tar.gz
gcc-ee9f00606f184be37d6f9df74cc7e222157c7fee.tar.bz2
libstdc++: Preserve signbit of nan when converting float to double [PR113578]
LWG 117 specifies that inserting a float into an ostream should cast it to double, because there's no std::num_put::put member that takes a float. However, on RISC-V converting a NaN float to double loses the sign, which means that negative NaN floats are printed as positive. This has been reported as LWG 4101 and there is good support for fixing the standard to preserve the sign bit when printing negative NaN values. This change uses copysign((double)f, (double)std::bit_cast<int>(f)) to get a double that preserves the sign. The bit_cast gives us an integer with the same signbit, and casting that to the target type preserves the signbit. We don't care about the value, as copysign only uses the signbit. The inserters for extended floating-point types need the same treatment, so add a new _S_cast_flt helper to do the signbit-preserving conversion generically. So far only RISC-V has been confirmed to need this treatment, but we might need to extend it to other targets later. libstdc++-v3/ChangeLog: PR libstdc++/113578 * include/std/ostream (_S_cast_flt): New static member function to restore signbit after casting to double or long double. (operator<<(float), operator<<(_Float16), operator<<(_Float32)) (operator<<(_Float64), operator(_Float128)) (operator<<(__bfloat16_t)): Use _S_cast_flt. testsuite/27_io/basic_ostream/inserters_arithmetic/lwg4101.cc: New test. Co-authored-by: Andrew Waterman <andrew@sifive.com>
Diffstat (limited to 'gcc')
0 files changed, 0 insertions, 0 deletions