Skip to content

Conversation

@statementreply
Copy link
Contributor

@statementreply statementreply commented Aug 9, 2020

[facet.num.put.virtuals]/5

For conversion from a floating-point type, if floatfield != (ios_­base​::​fixed | ios_­base​::​​scientific), str.precision() is specified as precision in the conversion specification. Otherwise, no precision is specified.

  • Hexfloat output ignores precision now as required by the standard.
  • Zero or negative precision is now correctly passed to sprintf. Implement LWG-231.
  • Output with negative precision no longer crashes.

Fixes #1125
Fixes AB#847068

@StephanTLavavej

This comment has been minimized.

@azure-pipelines

This comment has been minimized.

Copy link
Member

@BillyONeal BillyONeal left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Left some perf nitpicks and a question

1. Hexfloat output ignores precision now as required by the standard.

2. Precision of zero is now correctly passed to sprintf.

3. Fixed output with negative precision no longer crashes.
@statementreply
Copy link
Contributor Author

Reverted ABI breaking changes and force pushed.

@statementreply statementreply changed the title Fix ostream hexfloat output not ignoring precision Fix ostream << floating_point not correctly handling precision Aug 18, 2020
Copy link
Member

@StephanTLavavej StephanTLavavej left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wow, thanks for finding and fixing the additional bugs here! I wasn't too surprised by the hexfloat bug (hexfloats being relatively "new" and obscure to most users), and the negative precision crash involves a pathological input, but I still can't quite believe that the zero-precision bug for scientific and general has been lurking all this time.

Your new logic makes sense and I've verified that its behavior matches Clang's on Compiler Explorer, modulo the Windows/Linux difference in %a interpretation (the Windows UCRT prints out all 13 hexits, while Linux trims trailing 0 hexits; both are permitted by the C Standard).

Runtime behavior changes in floating-point formatting have the potential to be problematic from a compatibility perspective (the UCRT has struggled endlessly with this), but (1) users seem to find STL behavior changes far less problematic (I have previously fixed bugs in the early VS 2015 timeframe with zero user complaints), (2) I highly doubt that anyone will complain about the hexfloat behavior change, and (3) the zero-precision change also seems unlikely to pose compatibility issues, plus there is a workaround. (If someone was depending on our earlier behavior, they can simply pass a precision of 6.) The usual reason users have compatibility issues is when they're serializing results to a database or something and want all of the digits to be the same (even if the digits are wrong). However, since 6 is the default, I find it hard to imagine why a user would be setting the precision to 0.

@StephanTLavavej StephanTLavavej removed their assignment Aug 20, 2020
@StephanTLavavej
Copy link
Member

Aha - the zero-precision bug was noticed by a single user, four years ago, and the bug report got buried in our backlog. 😿

@StephanTLavavej StephanTLavavej self-assigned this Aug 21, 2020
@StephanTLavavej StephanTLavavej merged commit 0b81475 into microsoft:master Aug 22, 2020
@StephanTLavavej
Copy link
Member

Thanks again for the precise fixes! 😹

tautschnig added a commit to tautschnig/cbmc that referenced this pull request Nov 18, 2020
GitHub action runners now feature Visual Studio 16.8.1 (previously:
16.7). According to its STL changelog, this update includes the
following change:

microsoft/STL#1173 (review)

Therefore update the unit test to expect 13 trailing zeros.
tautschnig added a commit to tautschnig/cbmc that referenced this pull request Nov 18, 2020
GitHub action runners now feature Visual Studio 16.8.1 (previously:
16.7). According to its STL changelog, this update includes the
following change:

microsoft/STL#1173 (review)

Therefore update the unit test to expect 13 trailing zeros for MSVC
version >= 19.28.
trflynn89 added a commit to trflynn89/libfly that referenced this pull request Nov 29, 2020
1. Add /permissive flag to MSVC unit test compilation. As of 16.8, MSVC
   implicitly adds /permissive- when using /std:c++latest. See:

   https://docs.microsoft.com/en-us/cpp/build/reference/permissive-standards-conformance?view=msvc-160

   It seems that with this flag, MSVC fails to compile user-defined
   literals when prefixed with a negative sign, e.g. "-100_u8".

2. MSVC previously respected a stream's precision using std::hexfloat,
   which is non-compliant with the spec (std::hexfloat is meant to
   ignore precision). Unfortunately it does not behave the same as Clang
   and GCC still; MSVC will always zero-pad a fixed amount. See:

   microsoft/STL#1173
trflynn89 added a commit to trflynn89/libfly that referenced this pull request Nov 29, 2020
1. Add /permissive flag to MSVC unit test compilation. As of 16.8, MSVC
   implicitly adds /permissive- when using /std:c++latest. See:

   https://docs.microsoft.com/en-us/cpp/build/reference/permissive-standards-conformance?view=msvc-160

   It seems that with this flag, MSVC fails to compile user-defined
   literals when prefixed with a negative sign, e.g. "-100_u8".

2. MSVC previously respected a stream's precision using std::hexfloat,
   which is non-compliant with the spec (std::hexfloat is meant to
   ignore precision). Unfortunately it does not behave the same as Clang
   and GCC still; MSVC will always zero-pad a fixed amount. See:

   microsoft/STL#1173
@pabristow
Copy link

As part of a fuller test of Round-tripping decimal-binary-decimal on several compilers using iostream and charconv - see

roundtripping tests Jan2021.txt](https://github.com/microsoft/STL/files/5764778/roundtripping.tests.Jan2021.txt)

I am pleased confirm that hex format round-tripping hexfloat now works correctly using MSVC 16.9.0 preview 1.

@statementreply statementreply deleted the hexfloat_precision branch April 17, 2021 10:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

<iostream>: hexfloat stream output does not ignore precision as it should

7 participants