Movatterモバイル変換


[0]ホーム

URL:



This page is a snapshot from the LWG issues list, see theLibrary Active Issues List for more information and the meaning ofC++17 status.

2403.stof() should callstrtof() andwcstof()

Section: 27.4.5[string.conversions]Status:C++17Submitter: Stephan T. LavavejOpened: 2014-06-14Last modified: 2017-07-30

Priority:2

View all otherissues in [string.conversions].

View all issues withC++17 status.

Discussion:

stof() is currently specified to callstrtod()/wcstod() (which converts the given string todouble) and then it's specified to convert thatdouble tofloat. This performs rounding twice, which introduces error. Here's an example written up by James McNellis:

Consider the following numberX:

1.999999821186065729339276231257827021181583404541015625 (X)

This number is exactly representable in binary as:

1.111111111111111111111101000000000000000000000000000001* ^1st                  ^23rd                        ^52nd

I've marked the 23rd and 52nd fractional bits. These are the least significant bits forfloat anddouble, respectively.

If we convert this number directly tofloat, we take the 23 most significant bits:

1.11111111111111111111110

The next bit is a one and the tail is nonzero (the 54th fractional bit is a one), so we round up. This gives us the correctly rounded result:

1.11111111111111111111111

So far so good. But... If we convertX todouble, we take the 52 most significant bits:

1.1111111111111111111111010000000000000000000000000000 (Y)

The next bit is a zero, so we round down (truncating the value). If we then convertY tofloat, we take its 23 most significant bits:

1.11111111111111111111110

The next bit is a one and the tail is zero, so we round to even (leaving the value unchanged). This is off by 1ulp from the correctly rounded result.

[2014-06 Rapperswil]

Marshall Clow will look at this.

[Urbana 2014-11-07: Move to Ready]

Proposed resolution:

This wording is relative to N3936.

  1. Change 27.4.5[string.conversions] p4+p6 as indicated:

    float stof(const string& str, size_t* idx = 0);double stod(const string& str, size_t* idx = 0);long double stold(const string& str, size_t* idx = 0);

    -4-Effects:the first twoThese functions callstrtof(str.c_str(), ptr),strtod(str.c_str(), ptr), andthe third function callsstrtold(str.c_str(), ptr), respectively. Each function returns the converted result, if any. […]

    […]

    -6-Throws:invalid_argument ifstrtof,strtod, orstrtold reports that no conversion could be performed. Throwsout_of_range ifstrtof,strtod, orstrtold setserrno toERANGE or if the converted value is outside the range of representable values for the return type.

  2. Change 27.4.5[string.conversions] p11+p13 as indicated:

    float stof(const wstring& str, size_t* idx = 0);double stod(const wstring& str, size_t* idx = 0);long double stold(const wstring& str, size_t* idx = 0);

    -11-Effects:the first twoThese functions callwcstof(str.c_str(), ptr),wcstod(str.c_str(), ptr), andthe third function callswcstold(str.c_str(), ptr), respectively. Each function returns the converted result, if any. […]

    […]

    -13-Throws:invalid_argument ifwcstof,wcstod, orwcstold reports that no conversion could be performed. Throwsout_of_range ifwcstof,wcstod, orwcstold setserrno toERANGE.


[8]ページ先頭

©2009-2026 Movatter.jp