Topic: Deprecating to_string() for floating point types
Author: Moritz Klammler <moritz.klammler@gmail.com>
Date: Sun, 28 Feb 2016 17:38:47 +0100
Raw View
I have loosely followed the previous discussion and this is a nice
write-up. I have a few questions about your proposal.
It seems to me that you consider the ability to have lossless
round-trips important. I don't think I agree that a lack of this
property is an inconsistency with the `to_string` overloads for
integers. It's rather inherent to the nature of floating-point. If an
application needs value-preserving round-trips (as would be highly
desirable for storing numeric values in a text-based database, for
example), using "hexfloat" format would be an economic alternative that
is almost perfect except that a mere mortal human cannot make sense out
of the gibberish. It seems to me that formatting floating-point values
for storing in text format and parsing again later without loss and
formatting floating-point values for presentation to humans are very
distinct use-cases that should not be confused. `std::to_string` should
decide which use-case it wants to serve. I opt for the human interface
but then the value-preserving property of round-trips is less important
an argument. If we choose the other use-case, I'd really expect
"hexfloat" as an option. Your current draft doesn't mention "hexfloat"
at all.
How likely is it that actual software would be broken by changing
`std::to_string`'s definition from using `%f` to `%g`? Given all of its
problems discussed in your text, it seems to me that the author of any
application that uses `std::to_string` today probably didn't think too
much about corner cases anyway. Switching from `%f` to `%g` would be a
win for both, presenting to humans and storing for later re-use. I
think the potential damage would be very limited. Having `to_string`
overloaded for all built-in types is useful, especially for writing
generic code, so I wouldn't like to deprecate it easily if the
undeniable deficits can also be fixed reasonably.
> std::string to_string_f(double d,
> int precision =3D special_value_requesting_sh=
ortest_nonlossy_representation,
> char format =3D 'g') noexcept;
>
> [...]
>
> If precision or format is not within accepted range, to_string_f()
> returns empty string.
>
> - Handling of out-of-range parameter values should be revised and
> defined. The noexcept-property should however be preserved.
None of the `std::to_string` overloads today is `noexcept` and given
that `std::string`'s constructor isn't, they cannot realistically be.
Of course, in practice, SSO will often prevent the need for memory
allocation but besides the fact that the standard doesn't mandate it,
especially with very long floating-point representations, dynamic memory
allocation could easily be required.
I also don't think that silently returning an empty string is a good way
to communicate invalid inputs. And if I remember correctly, the
accepted practice is to only declare functions `noexcept` if they have
no preconditions.
Many of the conversion functions in =C2=A7 21.5 [string.conversions] are
specified to throw `std::invalid_argument` so I don't see why the
proposed `std::to_string_f` should deviate from this.
Finally, why does it have to be a new function? Couldn't the same
benefit be achieved by adding those default arguments to the existing
`to_string`? I see that you didn't want to change the `%f` requirement
but do like to use `%g` as default for the new function. But as
discussed above, I think that this is a risk we might well consider
worth taking.
--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/87lh647pt4.fsf%40gmail.com.
.
Author: d.h.gottwald@gmail.com
Date: Mon, 29 Feb 2016 07:47:51 -0800 (PST)
Raw View
------=_Part_179_173916395.1456760871783
Content-Type: multipart/alternative;
boundary="----=_Part_180_1243467156.1456760871783"
------=_Part_180_1243467156.1456760871783
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
Have you read the paper "How to print floating point numbers accurately",=
=20
e.g. from here: http://kurtstephens.com/files/p372-steele.pdf
This seems to cover some of the problems you described.
On Sunday, February 28, 2016 at 2:06:29 PM UTC+1, u97...@gmail.com wrote:
> This post continues Deprecate to_string() for floating point types?=20
> <https://groups.google.com/a/isocpp.org/forum/?fromgroups#!topic/std-disc=
ussion/6xhWgsEuvPo>
>
> The original thread served it purpose and it seemed more appropriate to=
=20
> start a new thread in this forum with a more proposal-like text for=20
> evaluation.
>
> ------------------------
>
> Summary
> --------------
>
> This document introduces the current behaviour of std::to_string()=20
> pointing out it's fundamental problems with floating point types and=20
> suggests a change to standard.
>
> Introduction
> -----------------
>
> Converting numeric values to string is a common task in contexts like UI'=
s=20
> and human readable files and common enough to be listed as a newbie=20
> question in C++ FAQ <https://isocpp.org/wiki/faq/newbie#int-to-string>=20
> [6]. Before C++11 there was no clear choice for conversion and some of th=
e=20
> options suggested [4]=20
> <http://stackoverflow.com/questions/5290089/how-to-convert-a-number-to-st=
ring-and-vice-versa-in-c>=20
> [5]=20
> <http://stackoverflow.com/questions/332111/how-do-i-convert-a-double-into=
-a-string-in-c>=20
> for the task were:
>
> 1. std::ostringstream
> 2. sprintf
> 3. boost::lexical_cast
>
> These have problems ranging from complexity and performance to buffer=20
> handling hazards and external dependency. With std::to_string() the gener=
al=20
> answer got easy: use std::to_string().
>
> This, however, is not a good answer for floating point types.
>
> Floating point types are by their nature trickier to deal with and it's=
=20
> harder to define what std::to_string() should do with floating point type=
s.
>
> The papers introducing std::to_string() [1]=20
> <http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1803.html> [2]=
=20
> <http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1982.html> [3]=
=20
> <http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2408.html> does=
=20
> not discuss the purpose of std::to_string() (i.e. what problem it is=20
> intended to solve) and the current standard simply defines that return=20
> string of std::to_string(double val) is identical to what sprintf(buf,=20
> "%f", val) would generate with sufficient buffer size buf.
>
> This paper argues that the decision is highly questionable, impractical=
=20
> and a source of bugs thus suggesting a change to the standard.
>
> Problem
> ------------
>
> In form of examples, the definition of std::to_string(double val)=20
> essentially as sprintf(buf, "%f", val) has the following implications:
>
> 1. std::to_string(double(0)) =3D=3D "0.000000"
> 2. std::to_string(double(10000)) =3D=3D "10000.000000"
> 3. std::to_string(double(1e300)) =3D=3D=20
> "100000000000000005250476025520442024870446858110815915491585411551180=
245798890819578637137508044786404370444383288387817694252323536043057564479=
218478670698284838720092657580373783023379478809005936895323497079994508111=
903896764088007465274278014249457925878882005684283811566947219638686545940=
0540160.000000"
> 4. std::to_string(double(1e-9)) =3D=3D "0.000000"
>
> While it's not obvious how the conversion should work for floating point=
=20
> types, it's hard to see that any acceptable implementation would have=20
> behaviour as shown above. The problems are:
>
> - Redundant characters from information preservation point of view (1,=
=20
> 2, 3, 4).
> - Unreadable output (3)
> - Failing to preserve even a single significant digit (4).
>
> While redundant decimal characters may be even desired in some use cases,=
=20
> the failure to preserve any significant digits is a serious issue=20
> especially as it is not a rare corner case issue but affects a big=20
> proportion of the whole double domain. How big a proportion? At least in=
=20
> common implementations of double, base 10 exponent can get values in rang=
e=20
> [-308, 308]. All values where exponent is in range [-308, -8] are convert=
ed=20
> to "0.000000" by std::to_string(). And given that readability of values=
=20
> with tens of digits is bad as demonstrated in example 3, the exponent ran=
ge=20
> where std::to_string() creates acceptable string representation is quite=
=20
> small although the good range may well cover the most frequent use cases.
>
> For comparison, here's a short survey of related implementations using=20
> double (or similar type) value 1.23456789e-9:
>
>
> - Visual Basic (VS2015) ToString() : "1.23456789E-09"
> - C# (VS2015) ToString() : "1.23456789E-09"
> - Java toString() : "1.23456789E-9"
> - JavaScript toString() : "1.23456789e-9"
> - boost::lexical_cast<std::string>(1.23456789e-9):=20
> "1.2345678899999999e-09"
> - Qt 5.4 QString::number(1.23456789e-9) : "1.23457e-09"=20
> - Qt 5.4 QVariant(1.23456789e-9).toString() : "1.23456789e-09"
> - C++ to_string(1.23456789e-9) : "0.000000"
>
>
> 8 implementations, in 5 the result is precision-wise identical to value=
=20
> written to source code, in 1 the result is non-lossy but longer than sour=
ce=20
> code version, in 1 the value is rounded to 6 significant digits and then=
=20
> there's std::to_string() that simply wipes out all significant digits.
>
> Ideal
> -------
>
> If std::to_string() for floating point types was created from scratch, th=
e=20
> question would be: what should it do? The following starting point is=20
> assumed:
>
>
> - std::to_string() for integer types is defined and their=20
> implementations are what they currently are.
> - to_string() is required to print (human readable) decimal=20
> representation also of floating point values.
>
>
> Some ideas:
>
>
> 1. With integer types, the following condition is true: x !=3D y <=3D>=
=20
> to_string(x) !=3D to_string(y). Also for related from_string() impleme=
ntation=20
> such as stoul(), stoul(to_string(x)) =3D=3D x for all x of type T. In =
plain=20
> words this means that one can convert integer to string and read it ba=
ck to=20
> get exactly the same item from which the string representation was cre=
ated=20
> from. To keep the semantics the same for floating point types, require=
the=20
> same property for floating point types.
> 2. std::cout -like implementation that uses a standard defined default=
=20
> number of significant digits that is less than needed for non-lossy=20
> conversion.
> 3. Use fixed decimal count.
> 4. Print value as close to mathematically exact value as possible.
>
> Option 4 would for example imply hugely long string representations as=20
> demonstrated earlier so it's not viable option.
>
> Option 3 is the current one and is obviously out of question.
>
> In option 2 to_string() is allowed to create an approximation meaning tha=
t=20
> to_string(x) =3D=3D to_string(y) for many different x and y thus changing=
the=20
> semantics compared to integer implementation. This is an essential=20
> difference so there should be a very good reason for choosing this. The=
=20
> argument is that there's none: prettiness and practicality arguments are=
=20
> use case specific that can't be defined on standard level.
>
> With this reasoning the only reasonable choice would be option 1. Notes o=
n=20
> it's implications:
>
>
> - The string representation is allowed to be ambiguous.
> - The string representation is not required to be mathematically=20
> exact: e.g. "1e300" is accepted because from_string(to_string(1e300)) =
=3D=3D=20
> from_string("1e300") even though mathematically double(1e300) !=3D 1e3=
00.
> - Resulting string may be long but even in worst case is much shorter=
=20
> than what current to_string() prints for big values. For smaller value=
s the=20
> resulting string may be shorter than with current to_string() because=
=20
> redundant decimals can be shortened (e.g. "1.0" vs "1.000000")
>
> In this context the ideal could be formulated as follows:
>
> to_string() with floating point types shall create such a string=20
> representation that for related from_string() implementation such as=20
> stod(), from_string(to_string(x)) =3D=3D x for all x in floating point ty=
pe=20
> domain. The string representation shall be portable across all=20
> implementations that use the same floating point implementation in the=20
> sense that reading the string in another implementation shall result to=
=20
> value exactly the same as from which the string was created from. The=20
> string representations are not, however, required to be identical on such=
=20
> implementations, but is it recommended to be shortest possible using=20
> similar scheme as defined in %g-family format in sprintf().
>
> How to change the standard
> ----------------------------------------
>
> Big complication is that to_string() can't be changed without introducing=
=20
> a (breaking) change. The change could be of various type:
>
>
> 1. Behaviour change on runtime: may break any existing code using the=
=20
> current definition.
> 2. Compilation breaking or deprecation change: safer alternative=20
> implemented by API-change causing a compilation failure.
> 3. Keep current behaviour but introduce parameters to make it possible=
=20
> to get a better behaviour.
>
>
> Not particularly nice choices, but the runtime behaviour change can be=20
> ruled out for starter leaving only two options. Breaking compilation or=
=20
> deprecation is undesired, but preferred to having numerous programmers=20
> making bugs due to this for decades to come. Thus the proposal is to=20
> deprecate current to_string for floating point types and introduce a new=
=20
> function with name to_string_f() or similar that behaves as described=20
> earlier. to_string_f() shall also take optional parameters that allows=20
> developer to fine tune the conversion like implemented e.g. in =20
> QString::number() <http://doc.qt.io/qt-5/qstring.html#number-6> [7].=20
> Options for fine tuning is important in the sense that making to_string_f=
()=20
> too simple and restricted will too quickly cause programmer to resort to=
=20
> old and lacking alternatives, although at this point the purpose of=20
> to_string_f() is not to act as full featured sprintf-like formatting=20
> implementation.
>
> Early draft suggestion
> -------------------------------
>
> (float, long double and wstring omitted for clarity):
>
> std::string to_string_f(double d, int precision =3D=20
> special_value_requesting_shortest_nonlossy_representation, char format =
=3D=20
> 'g') noexcept;
>
> Precision: Meaning depends on format-specifier as in sprintf in addition=
=20
> to special items.
> Format: Possible values: a, A, e, E, f, F, g, G as available for sprintf(=
).
>
> If precision or format is not within accepted range, to_string_f() return=
s=20
> empty string.
>
>
> Notes and open questions
> --------------------------------------
>
> -Usage examples and possible return values:
> to_string_f(1.0) -> "1.0"
> to_string_f(1.0, 10) -> "1.0"
> to_string_f(1.0, 2, 'f') -> "1.00"
> to_string_f(1.23456789e-9) -> "1.23456789e-9"
> to_string_f(1.23456789e-9, 2) -> "1.2e-9"
> to_string_f(1e300) -> "1e300"
>
>
> -The essential question: is it feasible to implemented the=20
> from_string(to_string(x)) =3D=3D x requirement given all the possible flo=
ating=20
> point implementations permitted by the C++ standard? If not, can the=20
> condition be fulfilled by not requiring it for some corner cases such as=
=20
> NaN's (e.g. having only single NaN instead of multiple)?
>
> -Having int and char as parameters instead of string such as "%.3f" is=20
> chosen for safety and simplicity: eliminates the need to do string parsin=
g=20
> and avoids possibility for errors in the users defined format string.
>
> -Shortest necessary string representation can't be acquired using=20
> sprintf() with maximal precision, but such implementation would be=20
> acceptable because shortest possible string is not required. This is chos=
en=20
> to avoid the need to define "shortest possible" which is not expected to=
=20
> have essential relevance for the usage of to_string_f(). Also the=20
> implementation effort from library implementers to guarantee the shortest=
=20
> possible on all standard conforming C++ implementations might be=20
> unnecessarily high.
>
> -For portability of string representation, see the end of section 'Ideal'
>
> -Should the default value for precision be, say, -1 or an enum given the=
=20
> conventions used for enums in std-namespace?=20
>
> -Handling of out-of-range parameter values should be revised and defined.=
=20
> The noexcept-property should however be preserved.
>
> -How to handle locale: implicitly use the same as sprintf or require that=
=20
> the output is locale independent? Locale-dependency would cause portabili=
ty=20
> issues so having locale-independent output would be desirable and in=20
> accordance with the design intention as to_string_f() is not intended to =
do=20
> full featured locale aware formatting.
>
> -Would to_string_f() be appropriate name?
>
>
> Details on examples
> -----------------------------
>
> Visual Basic (VS2015)
> Dim aDouble As Double
> aDouble =3D 0.00000000123456789
> Dim s As String =3D aDouble.ToString()
> Console.WriteLine(s)
> =20
> C# (VS2015)
> double a =3D 1.23456789e-9;
> String s =3D a.ToString();
> Console.Write(s);
> =20
> boost::lexical_cast (boost 1.55)
> auto s =3D boost::lexical_cast<std::string>(1.23456789e-9);
> std::cout << s;
> =20
> Java (sun-jdk-8u51)
> Double a =3D 1.23456789e-9;
> String s =3D a.toString();
> System.out.println(s);
> =20
> JavaScript (tested in Firefox 44)
> var dA =3D 1.23456789e-9;
> var sA =3D dA.toString();
> =20
> Qt (5.4)
> QString s =3D QString::number(1.23456789e-9);
> auto s2 =3D QVariant(1.23456789e-9).toString();
>
>
> References
> ----------
>
> [1] N1803: Simple Numeric Access.=20
> http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1803.html
> [2] N1982: Simple Numeric Access Revision 1.=20
> http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1982.html
> [3] N2408: Simple Numeric Access Revision 2.=20
> http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2408.html
> [4] How to convert a number to string and vice versa in C++.=20
> http://stackoverflow.com/questions/5290089/how-to-convert-a-number-to-str=
ing-and-vice-versa-in-c
> [5] How do I convert a double into a string in C++?.=20
> http://stackoverflow.com/questions/332111/how-do-i-convert-a-double-into-=
a-string-in-c
> [6] How do I convert an integer to a string?=20
> https://isocpp.org/wiki/faq/newbie#int-to-string
> [7] QString::number(). http://doc.qt.io/qt-5/qstring.html#number-6.
> =20
>
--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/89c4ad80-fd43-4c00-87fd-8dc38ba50739%40isocpp.or=
g.
------=_Part_180_1243467156.1456760871783
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div>Have you read the paper "How to print floating p=
oint numbers accurately", e.g. from here: <a href=3D"http://kurtstephe=
ns.com/files/p372-steele.pdf">http://kurtstephens.com/files/p372-steele.pdf=
</a></div><div>This seems to cover some of the problems you described.<br><=
br>On Sunday, February 28, 2016 at 2:06:29 PM UTC+1, u97...@gmail.com wrote=
:</div><blockquote class=3D"gmail_quote" style=3D"margin: 0px 0px 0px 0.8ex=
; padding-left: 1ex; border-left-color: rgb(204, 204, 204); border-left-wid=
th: 1px; border-left-style: solid;"><div dir=3D"ltr">This post continues=C2=
=A0<a onmousedown=3D"this.href=3D'https://groups.google.com/a/isocpp.or=
g/forum/?fromgroups#!topic/std-discussion/6xhWgsEuvPo';return true;" on=
click=3D"this.href=3D'https://groups.google.com/a/isocpp.org/forum/?fro=
mgroups#!topic/std-discussion/6xhWgsEuvPo';return true;" href=3D"https:=
//groups.google.com/a/isocpp.org/forum/?fromgroups#!topic/std-discussion/6x=
hWgsEuvPo" target=3D"_blank" rel=3D"nofollow">Deprecate to_string() for flo=
ating point types?</a><br><br>The original thread served it purpose and it =
seemed more appropriate to start a new thread in this forum with a more pro=
posal-like text for evaluation.<br><br>------------------------<br><br>Summ=
ary<br>--------------<br><br>This document introduces the current behaviour=
of std::to_string() pointing out it's fundamental problems with floati=
ng point types and suggests a change to standard.<br><br>Introduction<br>--=
---------------<br><br>Converting numeric values to string is a common task=
in contexts like UI's and human readable files and common enough to be=
listed as a newbie question in <a onmousedown=3D"this.href=3D'https://=
www.google.com/url?q\75https%3A%2F%2Fisocpp.org%2Fwiki%2Ffaq%2Fnewbie%23int=
-to-string\46sa\75D\46sntz\0751\46usg\75AFQjCNGRrs0D8gCHf_L3woAssxIChXqR_A&=
#39;;return true;" onclick=3D"this.href=3D'https://www.google.com/url?q=
\75https%3A%2F%2Fisocpp.org%2Fwiki%2Ffaq%2Fnewbie%23int-to-string\46sa\75D\=
46sntz\0751\46usg\75AFQjCNGRrs0D8gCHf_L3woAssxIChXqR_A';return true;" h=
ref=3D"https://isocpp.org/wiki/faq/newbie#int-to-string" target=3D"_blank" =
rel=3D"nofollow">C++ FAQ</a> [6]. Before C++11 there was no clear choice fo=
r conversion and some of the options suggested=C2=A0<a onmousedown=3D"this.=
href=3D'http://www.google.com/url?q\75http%3A%2F%2Fstackoverflow.com%2F=
questions%2F5290089%2Fhow-to-convert-a-number-to-string-and-vice-versa-in-c=
\46sa\75D\46sntz\0751\46usg\75AFQjCNFlCKhMoCuothv_g6Vy-YlJxppPHQ';retur=
n true;" onclick=3D"this.href=3D'http://www.google.com/url?q\75http%3A%=
2F%2Fstackoverflow.com%2Fquestions%2F5290089%2Fhow-to-convert-a-number-to-s=
tring-and-vice-versa-in-c\46sa\75D\46sntz\0751\46usg\75AFQjCNFlCKhMoCuothv_=
g6Vy-YlJxppPHQ';return true;" href=3D"http://stackoverflow.com/question=
s/5290089/how-to-convert-a-number-to-string-and-vice-versa-in-c" target=3D"=
_blank" rel=3D"nofollow">[4]</a> <a onmousedown=3D"this.href=3D'http://=
www.google.com/url?q\75http%3A%2F%2Fstackoverflow.com%2Fquestions%2F332111%=
2Fhow-do-i-convert-a-double-into-a-string-in-c\46sa\75D\46sntz\0751\46usg\7=
5AFQjCNHyDCuwvFEuXRS-gnX4sF_EeV9Z4Q';return true;" onclick=3D"this.href=
=3D'http://www.google.com/url?q\75http%3A%2F%2Fstackoverflow.com%2Fques=
tions%2F332111%2Fhow-do-i-convert-a-double-into-a-string-in-c\46sa\75D\46sn=
tz\0751\46usg\75AFQjCNHyDCuwvFEuXRS-gnX4sF_EeV9Z4Q';return true;" href=
=3D"http://stackoverflow.com/questions/332111/how-do-i-convert-a-double-int=
o-a-string-in-c" target=3D"_blank" rel=3D"nofollow">[5]</a> for the task we=
re:<br><ol><li>std::ostringstream</li><li>sprintf</li><li>boost::lexical_ca=
st</li></ol>These have problems ranging from complexity and performance to =
buffer handling hazards and external dependency. With std::to_string() the =
general answer got easy: use std::to_string().<br><br>This, however, is not=
a good answer for floating point types.<br><br>Floating point types are by=
their nature trickier to deal with and it's harder to define what std:=
:to_string() should do with floating point types.<br><br>The papers introdu=
cing std::to_string()=C2=A0<a onmousedown=3D"this.href=3D'http://www.go=
ogle.com/url?q\75http%3A%2F%2Fwww.open-std.org%2Fjtc1%2Fsc22%2Fwg21%2Fdocs%=
2Fpapers%2F2005%2Fn1803.html\46sa\75D\46sntz\0751\46usg\75AFQjCNHjrL_pJ-36q=
wuD7j12_iXKbF26sA';return true;" onclick=3D"this.href=3D'http://www=
..google.com/url?q\75http%3A%2F%2Fwww.open-std.org%2Fjtc1%2Fsc22%2Fwg21%2Fdo=
cs%2Fpapers%2F2005%2Fn1803.html\46sa\75D\46sntz\0751\46usg\75AFQjCNHjrL_pJ-=
36qwuD7j12_iXKbF26sA';return true;" href=3D"http://www.open-std.org/jtc=
1/sc22/wg21/docs/papers/2005/n1803.html" target=3D"_blank" rel=3D"nofollow"=
>[1]</a>=C2=A0<a onmousedown=3D"this.href=3D'http://www.google.com/url?=
q\75http%3A%2F%2Fwww.open-std.org%2Fjtc1%2Fsc22%2Fwg21%2Fdocs%2Fpapers%2F20=
06%2Fn1982.html\46sa\75D\46sntz\0751\46usg\75AFQjCNFBfwL0rpTneyr6ayTuGDMTCP=
NzdA';return true;" onclick=3D"this.href=3D'http://www.google.com/u=
rl?q\75http%3A%2F%2Fwww.open-std.org%2Fjtc1%2Fsc22%2Fwg21%2Fdocs%2Fpapers%2=
F2006%2Fn1982.html\46sa\75D\46sntz\0751\46usg\75AFQjCNFBfwL0rpTneyr6ayTuGDM=
TCPNzdA';return true;" href=3D"http://www.open-std.org/jtc1/sc22/wg21/d=
ocs/papers/2006/n1982.html" target=3D"_blank" rel=3D"nofollow">[2]</a>=C2=
=A0<a onmousedown=3D"this.href=3D'http://www.google.com/url?q\75http%3A=
%2F%2Fwww.open-std.org%2Fjtc1%2Fsc22%2Fwg21%2Fdocs%2Fpapers%2F2007%2Fn2408.=
html\46sa\75D\46sntz\0751\46usg\75AFQjCNETf6GEwa4_6JF_jadbb9qjoidZ7w';r=
eturn true;" onclick=3D"this.href=3D'http://www.google.com/url?q\75http=
%3A%2F%2Fwww.open-std.org%2Fjtc1%2Fsc22%2Fwg21%2Fdocs%2Fpapers%2F2007%2Fn24=
08.html\46sa\75D\46sntz\0751\46usg\75AFQjCNETf6GEwa4_6JF_jadbb9qjoidZ7w'=
;;return true;" href=3D"http://www.open-std.org/jtc1/sc22/wg21/docs/papers/=
2007/n2408.html" target=3D"_blank" rel=3D"nofollow">[3]</a> does not discus=
s the purpose of std::to_string() (i.e. what problem it is intended to solv=
e) and the current standard simply defines that return string of std::to_st=
ring(double val) is identical to what sprintf(buf, "%f", val) wou=
ld generate with sufficient buffer size buf.<br><br>This paper argues that =
the decision is highly questionable, impractical and a source of bugs thus =
suggesting a change to the standard.<br><br>Problem<br>------------<br><br>=
In form of examples, the definition of std::to_string(double val) essential=
ly as sprintf(buf, "%f", val) has the following implications:<br>=
<ol><li>std::to_string(double(0)) =3D=3D "0.000000"</li><li>std::=
to_string(double(10000)) =3D=3D "10000.000000"</li><li>std::to_st=
ring(double(1e300)) =3D=3D=20
"<wbr>100000000000000005250476025520<wbr>44202487044685811081591549158=
5<wbr>411551180245798890819578637137<wbr>508044786404370444383288387817<wbr=
>694252323536043057564479218478<wbr>670698284838720092657580373783<wbr>0233=
79478809005936895323497079<wbr>994508111903896764088007465274<wbr>278014249=
457925878882005684283<wbr>811566947219638686545940054016<wbr>0.000000"=
</li><li>std::to_string(double(1e-9)) =3D=3D "0.000000"</li></ol>=
While it's not obvious how the conversion should work for floating poin=
t types, it's hard to see that any acceptable implementation would have=
behaviour as shown above. The problems are:<br><ul><li>Redundant character=
s from information preservation point of view (1, 2, 3, 4).</li><li>Unreada=
ble output (3)</li><li>Failing to preserve even a single significant digit =
(4).</li></ul>While redundant decimal characters may be even desired in som=
e use cases, the failure to preserve any significant digits is a serious is=
sue especially as it is not a rare corner case issue but affects a big prop=
ortion of the whole double domain. How big a proportion? At least in common=
implementations of double, base 10 exponent can get values in range [-308,=
308]. All values where exponent is in range [-308, -8] are converted to &q=
uot;0.000000" by std::to_string(). And given that readability of value=
s with tens of digits is bad as demonstrated in example 3, the exponent ran=
ge where std::to_string() creates acceptable string representation is quite=
small although the good range may well cover the most frequent use cases.<=
br><br>For comparison, here's a short survey of related implementations=
using double (or similar type) value 1.23456789e-9:<br><br><ul><li>Visual =
Basic (VS2015) ToString() : "1.23456789E-09"</li><li>C# (VS2015) =
ToString() : "1.23456789E-09"</li><li>Java toString() : "1.2=
3456789E-9"</li><li>JavaScript toString() : "1.23456789e-9"<=
/li><li>boost::lexical_cast<std::<wbr>string>(1.23456789e-9): "1=
..2345678899999999e-09"</li><li>Qt 5.4 QString::number(1.23456789e-9) :=
"1.23457e-09" </li><li>Qt 5.4 QVariant(1.23456789e-9).<wbr>toStr=
ing() : "1.23456789e-09"</li><li>C++ to_string(1.23456789e-9) : &=
quot;0.000000"</li></ul><br>8 implementations, in 5 the result is prec=
ision-wise identical to value written to source code, in 1 the result is no=
n-lossy but longer than source code version, in 1 the value is rounded to 6=
significant digits and then there's std::to_string() that simply wipes=
out all significant digits.<br><br>Ideal<br>-------<br><br>If std::to_stri=
ng() for floating point types was created from scratch, the question would =
be: what should it do? The following starting point is assumed:<br><br><ul>=
<li>std::to_string() for integer types is defined and their implementations=
are what they currently are.</li><li>to_string() is required to print (hum=
an readable) decimal representation also of floating point values.</li></ul=
><br>Some ideas:<br><br><ol><li>With integer types, the following condition=
is true: x !=3D y <=3D>=20
to_string(x) !=3D to_string(y). Also for related from_string()=20
implementation such as stoul(), stoul(to_string(x)) =3D=3D x for all x of=
=20
type T. In plain words this means that one can convert integer to string
and read it back to get exactly the same item from which the string=20
representation was created from. To keep the semantics the same for=20
floating point types, require the same property for floating point=20
types.</li><li>std::cout -like implementation that uses a standard defined =
default number of significant
digits that=20
is less than needed for non-lossy conversion.</li><li>Use fixed decimal cou=
nt.</li><li>Print value as close to mathematically exact value as possible.=
</li></ol>Option 4 would for example imply hugely long string representatio=
ns as demonstrated earlier so it's not viable option.<br><br>Option 3 i=
s the current one and is obviously out of question.<br><br>In option 2 to_s=
tring() is allowed to create an approximation meaning that to_string(x) =3D=
=3D to_string(y) for many different x and y thus changing the semantics com=
pared to integer implementation. This is an essential difference so there s=
hould be a very good reason for choosing this. The argument is that there&#=
39;s none: prettiness and practicality arguments are use case specific that=
can't be defined on standard level.<br><br>With this reasoning the onl=
y reasonable choice would be option 1. Notes on it's implications:<br><=
br><ul><li>The string representation is allowed to be ambiguous.</li><li>Th=
e string representation is not required to be mathematically exact:=20
e.g. "1e300" is accepted because from_string(to_string(1e300)) =
=3D=3D=20
from_string("1e300") even though mathematically double(1e300) !=
=3D 1e300.</li><li>Resulting string may be long but even in worst case is m=
uch shorter than
what current to_string() prints for big values. For smaller values the=20
resulting string may be shorter than with current to_string() because=20
redundant decimals can be shortened (e.g. "1.0" vs "1.000000=
")</li></ul>In this context the ideal could be formulated as follows:<=
br><br>to_string() with floating point types shall create such a string rep=
resentation that for related from_string() implementation such as stod(), f=
rom_string(to_string(x)) =3D=3D x for all x in floating point type domain. =
The string representation shall be portable across all implementations that=
use the same floating point implementation in the sense that reading the s=
tring in another implementation shall result to value exactly the same as f=
rom which the string was created from. The string representations are not, =
however, required to be identical on such implementations, but is it recomm=
ended to be shortest possible using similar scheme as defined in %g-family =
format in sprintf().<br><br>How to change the standard<br>-----------------=
-------------<wbr>----------<br><br>Big complication is that to_string() ca=
n't be changed without introducing a (breaking) change. The change coul=
d be of various type:<br><br><ol><li>Behaviour change on runtime: may break=
any existing code using the current definition.</li><li>Compilation breaki=
ng or deprecation change: safer alternative implemented by API-change causi=
ng a compilation failure.</li><li>Keep current behaviour but introduce para=
meters to make it possible to get a better behaviour.</li></ol><br>Not part=
icularly nice choices, but the runtime behaviour change can be ruled out fo=
r starter leaving only two options. Breaking compilation or deprecation is =
undesired, but preferred to having numerous programmers making bugs due to =
this for decades to come. Thus the proposal is to deprecate current to_stri=
ng for floating point types and introduce a new function with name to_strin=
g_f() or similar that behaves as described earlier. to_string_f() shall als=
o take optional parameters that allows developer to fine tune the conversio=
n like implemented e.g. in=C2=A0 <a onmousedown=3D"this.href=3D'http://=
www.google.com/url?q\75http%3A%2F%2Fdoc.qt.io%2Fqt-5%2Fqstring.html%23numbe=
r-6\46sa\75D\46sntz\0751\46usg\75AFQjCNGB80DqmFeKsIBuDRHvOqvFC7XhFg';re=
turn true;" onclick=3D"this.href=3D'http://www.google.com/url?q\75http%=
3A%2F%2Fdoc.qt.io%2Fqt-5%2Fqstring.html%23number-6\46sa\75D\46sntz\0751\46u=
sg\75AFQjCNGB80DqmFeKsIBuDRHvOqvFC7XhFg';return true;" href=3D"http://d=
oc.qt.io/qt-5/qstring.html#number-6" target=3D"_blank" rel=3D"nofollow">QSt=
ring::number()</a> [7]. Options for fine tuning is important in the sense t=
hat making to_string_f() too simple and restricted will too quickly cause p=
rogrammer to resort to old and lacking alternatives, although at this point=
the purpose of to_string_f() is not to act as full featured sprintf-like f=
ormatting implementation.<br><br>Early draft suggestion<br>----------------=
--------------<wbr>-<br><br>(float, long double and wstring omitted for cla=
rity):<br><br>std::string to_string_f(double d, int precision =3D special_v=
alue_requesting_<wbr>shortest_nonlossy_<wbr>representation, char format =3D=
'g') noexcept;<br><br>Precision: Meaning depends on format-specifi=
er as in sprintf in addition to special items.<br>Format: Possible values: =
a, A, e, E, f, F, g, G as available for sprintf().<br><br>If precision or f=
ormat is not within accepted range, to_string_f() returns empty string.<br>=
<br><br>Notes and open questions<br>------------------------------<wbr>----=
----<br><br>-Usage examples and possible return values:<br>=C2=A0=C2=A0=C2=
=A0 to_string_f(1.0) -> "1.0"<br>=C2=A0=C2=A0=C2=A0 to_string_=
f(1.0, 10) -> "1.0"<br>=C2=A0=C2=A0=C2=A0 to_string_f(1.0, 2, =
'f') -> "1.00"<br>=C2=A0=C2=A0=C2=A0 to_string_f(1.234=
56789e-9) -> "1.23456789e-9"<br>=C2=A0=C2=A0=C2=A0 to_string_f=
(1.23456789e-9, 2) -> "1.2e-9"<br>=C2=A0=C2=A0=C2=A0 to_string=
_f(1e300) -> "1e300"<br><br><br>-The essential question: is it=
feasible to implemented the from_string(to_string(x)) =3D=3D x requirement=
given all the possible floating point implementations permitted by the C++=
standard? If not, can the condition be fulfilled by not requiring it for s=
ome corner cases such as NaN's (e.g. having only single NaN instead of =
multiple)?<br><br>-Having int and char as parameters instead of string such=
as "%.3f" is chosen for safety and simplicity: eliminates the ne=
ed to do string parsing and avoids possibility for errors in the users defi=
ned format string.<br><br>-Shortest necessary string representation can'=
;t be acquired using sprintf() with maximal precision, but such implementat=
ion would be acceptable because shortest possible string is not required. T=
his is chosen to avoid the need to define "shortest possible" whi=
ch is not expected to have essential relevance for the usage of to_string_f=
(). Also the implementation effort from library implementers to guarantee t=
he shortest possible on all standard conforming C++ implementations might b=
e unnecessarily high.<br><br>-For portability of string representation, see=
the end of section 'Ideal'<br><br>-Should the default value for pr=
ecision be, say, -1 or an enum given the conventions used for enums in std-=
namespace? <br><br>-Handling of out-of-range parameter values should be rev=
ised and defined. The noexcept-property should however be preserved.<br><br=
>-How to handle locale: implicitly use the same as sprintf or require that =
the output is locale independent? Locale-dependency would cause portability=
issues so having locale-independent output would be desirable and in accor=
dance with the design intention as to_string_f() is not intended to do full=
featured locale aware formatting.<br><br>-Would to_string_f() be appropria=
te name?<br><br><br>Details on examples<br>-----------------------------<br=
><br>Visual Basic (VS2015)<br>=C2=A0=C2=A0=C2=A0 Dim aDouble As Double<br>=
=C2=A0=C2=A0=C2=A0 aDouble =3D 0.00000000123456789<br>=C2=A0=C2=A0=C2=A0 Di=
m s As String =3D aDouble.ToString()<br>=C2=A0=C2=A0=C2=A0 Console.WriteLin=
e(s)<br>=C2=A0=C2=A0=C2=A0 <br>C# (VS2015)<br>=C2=A0=C2=A0=C2=A0 double a =
=3D 1.23456789e-9;<br>=C2=A0=C2=A0=C2=A0 String s =3D a.ToString();<br>=C2=
=A0=C2=A0=C2=A0 Console.Write(s);<br>=C2=A0=C2=A0=C2=A0 <br>boost::lexical_=
cast (boost 1.55)<br>=C2=A0=C2=A0=C2=A0 auto s =3D boost::lexical_cast<s=
td::<wbr>string>(1.23456789e-9);<br>=C2=A0=C2=A0=C2=A0 std::cout <<=
; s;<br>=C2=A0=C2=A0=C2=A0 <br>Java (sun-jdk-8u51)<br>=C2=A0=C2=A0=C2=A0 Do=
uble a =3D 1.23456789e-9;<br>=C2=A0=C2=A0=C2=A0 String s =3D a.toString();<=
br>=C2=A0=C2=A0=C2=A0 System.out.println(s);<br>=C2=A0=C2=A0=C2=A0 <br>Java=
Script (tested in Firefox 44)<br>=C2=A0=C2=A0=C2=A0 var dA =3D 1.23456789e-=
9;<br>=C2=A0=C2=A0=C2=A0 var sA =3D dA.toString();<br>=C2=A0=C2=A0=C2=A0 <b=
r>Qt (5.4)<br>=C2=A0=C2=A0=C2=A0 QString s =3D QString::number(1.23456789e-=
9)<wbr>;<br>=C2=A0=C2=A0=C2=A0 auto s2 =3D QVariant(1.23456789e-9).<wbr>toS=
tring();<br><br><br>References<br>----------<br><br>[1] N1803: Simple Numer=
ic Access. <a onmousedown=3D"this.href=3D'http://www.google.com/url?q\7=
5http%3A%2F%2Fwww.open-std.org%2Fjtc1%2Fsc22%2Fwg21%2Fdocs%2Fpapers%2F2005%=
2Fn1803.html\46sa\75D\46sntz\0751\46usg\75AFQjCNHjrL_pJ-36qwuD7j12_iXKbF26s=
A';return true;" onclick=3D"this.href=3D'http://www.google.com/url?=
q\75http%3A%2F%2Fwww.open-std.org%2Fjtc1%2Fsc22%2Fwg21%2Fdocs%2Fpapers%2F20=
05%2Fn1803.html\46sa\75D\46sntz\0751\46usg\75AFQjCNHjrL_pJ-36qwuD7j12_iXKbF=
26sA';return true;" href=3D"http://www.open-std.org/jtc1/sc22/wg21/docs=
/papers/2005/n1803.html" target=3D"_blank" rel=3D"nofollow">http://www.open=
-std.org/jtc1/<wbr>sc22/wg21/docs/papers/2005/<wbr>n1803.html</a><br>[2] N1=
982: Simple Numeric Access Revision 1. <a onmousedown=3D"this.href=3D'h=
ttp://www.google.com/url?q\75http%3A%2F%2Fwww.open-std.org%2Fjtc1%2Fsc22%2F=
wg21%2Fdocs%2Fpapers%2F2006%2Fn1982.html\46sa\75D\46sntz\0751\46usg\75AFQjC=
NFBfwL0rpTneyr6ayTuGDMTCPNzdA';return true;" onclick=3D"this.href=3D=
9;http://www.google.com/url?q\75http%3A%2F%2Fwww.open-std.org%2Fjtc1%2Fsc22=
%2Fwg21%2Fdocs%2Fpapers%2F2006%2Fn1982.html\46sa\75D\46sntz\0751\46usg\75AF=
QjCNFBfwL0rpTneyr6ayTuGDMTCPNzdA';return true;" href=3D"http://www.open=
-std.org/jtc1/sc22/wg21/docs/papers/2006/n1982.html" target=3D"_blank" rel=
=3D"nofollow">http://www.open-std.org/jtc1/<wbr>sc22/wg21/docs/papers/2006/=
<wbr>n1982.html</a><br>[3] N2408: Simple Numeric Access Revision 2. <a onmo=
usedown=3D"this.href=3D'http://www.google.com/url?q\75http%3A%2F%2Fwww.=
open-std.org%2Fjtc1%2Fsc22%2Fwg21%2Fdocs%2Fpapers%2F2007%2Fn2408.html\46sa\=
75D\46sntz\0751\46usg\75AFQjCNETf6GEwa4_6JF_jadbb9qjoidZ7w';return true=
;" onclick=3D"this.href=3D'http://www.google.com/url?q\75http%3A%2F%2Fw=
ww.open-std.org%2Fjtc1%2Fsc22%2Fwg21%2Fdocs%2Fpapers%2F2007%2Fn2408.html\46=
sa\75D\46sntz\0751\46usg\75AFQjCNETf6GEwa4_6JF_jadbb9qjoidZ7w';return t=
rue;" href=3D"http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2408=
..html" target=3D"_blank" rel=3D"nofollow">http://www.open-std.org/jtc1/<wbr=
>sc22/wg21/docs/papers/2007/<wbr>n2408.html</a><br>[4] How to convert a num=
ber to string and vice versa in C++. <a onmousedown=3D"this.href=3D'htt=
p://www.google.com/url?q\75http%3A%2F%2Fstackoverflow.com%2Fquestions%2F529=
0089%2Fhow-to-convert-a-number-to-string-and-vice-versa-in-c\46sa\75D\46snt=
z\0751\46usg\75AFQjCNFlCKhMoCuothv_g6Vy-YlJxppPHQ';return true;" onclic=
k=3D"this.href=3D'http://www.google.com/url?q\75http%3A%2F%2Fstackoverf=
low.com%2Fquestions%2F5290089%2Fhow-to-convert-a-number-to-string-and-vice-=
versa-in-c\46sa\75D\46sntz\0751\46usg\75AFQjCNFlCKhMoCuothv_g6Vy-YlJxppPHQ&=
#39;;return true;" href=3D"http://stackoverflow.com/questions/5290089/how-t=
o-convert-a-number-to-string-and-vice-versa-in-c" target=3D"_blank" rel=3D"=
nofollow">http://stackoverflow.com/<wbr>questions/5290089/how-to-<wbr>conve=
rt-a-number-to-string-<wbr>and-vice-versa-in-c</a><br>[5] How do I convert =
a double into a string in C++?. <a onmousedown=3D"this.href=3D'http://w=
ww.google.com/url?q\75http%3A%2F%2Fstackoverflow.com%2Fquestions%2F332111%2=
Fhow-do-i-convert-a-double-into-a-string-in-c\46sa\75D\46sntz\0751\46usg\75=
AFQjCNHyDCuwvFEuXRS-gnX4sF_EeV9Z4Q';return true;" onclick=3D"this.href=
=3D'http://www.google.com/url?q\75http%3A%2F%2Fstackoverflow.com%2Fques=
tions%2F332111%2Fhow-do-i-convert-a-double-into-a-string-in-c\46sa\75D\46sn=
tz\0751\46usg\75AFQjCNHyDCuwvFEuXRS-gnX4sF_EeV9Z4Q';return true;" href=
=3D"http://stackoverflow.com/questions/332111/how-do-i-convert-a-double-int=
o-a-string-in-c" target=3D"_blank" rel=3D"nofollow">http://stackoverflow.co=
m/<wbr>questions/332111/how-do-i-<wbr>convert-a-double-into-a-<wbr>string-i=
n-c</a><br>[6] How do I convert an integer to a string? <a onmousedown=3D"t=
his.href=3D'https://www.google.com/url?q\75https%3A%2F%2Fisocpp.org%2Fw=
iki%2Ffaq%2Fnewbie%23int-to-string\46sa\75D\46sntz\0751\46usg\75AFQjCNGRrs0=
D8gCHf_L3woAssxIChXqR_A';return true;" onclick=3D"this.href=3D'http=
s://www.google.com/url?q\75https%3A%2F%2Fisocpp.org%2Fwiki%2Ffaq%2Fnewbie%2=
3int-to-string\46sa\75D\46sntz\0751\46usg\75AFQjCNGRrs0D8gCHf_L3woAssxIChXq=
R_A';return true;" href=3D"https://isocpp.org/wiki/faq/newbie#int-to-st=
ring" target=3D"_blank" rel=3D"nofollow">https://isocpp.org/wiki/faq/<wbr>n=
ewbie#int-to-string</a><br>[7] QString::number(). <a onmousedown=3D"this.hr=
ef=3D'http://www.google.com/url?q\75http%3A%2F%2Fdoc.qt.io%2Fqt-5%2Fqst=
ring.html%23number-6\46sa\75D\46sntz\0751\46usg\75AFQjCNGB80DqmFeKsIBuDRHvO=
qvFC7XhFg';return true;" onclick=3D"this.href=3D'http://www.google.=
com/url?q\75http%3A%2F%2Fdoc.qt.io%2Fqt-5%2Fqstring.html%23number-6\46sa\75=
D\46sntz\0751\46usg\75AFQjCNGB80DqmFeKsIBuDRHvOqvFC7XhFg';return true;"=
href=3D"http://doc.qt.io/qt-5/qstring.html#number-6" target=3D"_blank" rel=
=3D"nofollow">http://doc.qt.io/qt-5/qstring.<wbr>html#number-6</a>.<br>=C2=
=A0=C2=A0=C2=A0 <br></div></blockquote></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/89c4ad80-fd43-4c00-87fd-8dc38ba50739%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/89c4ad80-fd43-4c00-87fd-8dc38ba50739=
%40isocpp.org</a>.<br />
------=_Part_180_1243467156.1456760871783--
------=_Part_179_173916395.1456760871783--
.
Author: u97234@gmail.com
Date: Mon, 29 Feb 2016 15:26:49 -0800 (PST)
Raw View
------=_Part_1064_1984918039.1456788409595
Content-Type: multipart/alternative;
boundary="----=_Part_1065_885126106.1456788409596"
------=_Part_1065_885126106.1456788409596
Content-Type: text/plain; charset=UTF-8
Thanks for the responses.
@d.h.go...
I haven't, might be a good idea to do so.
@Moritz Klammler
About the inconsistency with integer versions, importance of round-tripping
and hexfloat
The inconsistency is in some sense hard to evaluate because, as mentioned,
the original paper did not specify the purpose of to_string(). In many use
cases such as human readable files using hexfloat might be a fundamental
change to usability: for example I would reckon that it's quite different
for interoperability with other tools (spreadsheet etc.) to have a file
with %g-formatted values compared to hexfloats. And using it is even harder
to justify when one can use non-lossy decimal representation. But requiring
round-tripping might actually be indirect: what if it is not required? What
should to_string() do? If the suggestion is a lossy precision, the
arguments can directly address the question why the chosen number of digits
can be considered a "fits for all" choice. Of course round-tripping format
does not fit for all, but I considered loss of information much bigger an
issue than having an inconvenience in the output; standard can't make a
guarantee that the formatted looks nice and has the right number of digits
for everyone, but it could guarantee some aspects of information
preservation for everyone.
hexfloat is by my understanding available through options 'a' and 'A'.
Likelihood of causing breaking changes
Generally speaking if a developer has created an application relying on a
standard guaranteed behaviour, any change can be a breaking one (here for
example one could be assuming that the result does not contain character
'e'). Especially the silent runtime behaviour change is potentially
hazardous.
Use of exceptions
Unfortunately the noexcept seems to be out of question due to the potential
allocation of std::string. thanks for pointing that out. Why the (direct)
use of exceptions such as std::invalid_argument does not seem appropriate
is that it seems a bit too severe a consequence that failing to create a
string would in practice often crash the application; i.e. people would
forget to use try-catch with to_string(). It's not a serious error if
conversion fails as the function can simply report "I got garbage, I can't
give an answer and you can check this from the return value if interested".
If the failure is a serious error for the application, it should handle it
accordingly. But this is more a question of when and why the standard seems
appropriate to use exception and how to apply it in this case if this ever
proceed to such stage.
"Finally, why does it have to be a new function?"
Because any change is potentially a breaking change; if experienced
standard people feel the expected consequences are negligible, personally I
would probably use to_string() more happily than to_string_f(). And while
"%g" would have been better than "%f" in some sense, %g implies only 6
significant digits which also has a severe problem:
const auto t = std::time(nullptr);
const auto d = static_cast<double>(t);
if (t == d)
{
char szBuffer[128];
std::cout << "Values are identical\n"
<< "to_string(t) = " << std::to_string(t) << '\n'
<< "to_string(d) = " << std::to_string(d) << '\n';
sprintf(szBuffer, "%g", d);
std::cout << "to_string(d) if %g instead of %f = " << szBuffer <<
'\n';
}
Example output:
Values are identical
to_string(t) = 1456783429
to_string(d) = 1456783429.000000
to_string(d) if %g instead of %f = 1.45678e+09
So with %g identical values would result to fundamentally different strings
depending on type. So simply changing %f -> %g might result to loss of
precision and severely break existing code on runtime. And if setting a
higher precision to avoid this, the question is how precise? The proposal
would make it easy: it's precise enough that there's no need to worry about
it.
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/47b6a73e-1ead-4536-b2e4-ca00402a2324%40isocpp.org.
------=_Part_1065_885126106.1456788409596
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">Thanks for the responses.<br><br>@d.h.go...<div dir=3D"ltr=
"><br>I haven't, might be a good idea to do so.<br><br>@Moritz Klammler=
<br><br><div style=3D"margin-left: 40px;">About the inconsistency with inte=
ger versions, importance of round-tripping and hexfloat<br></div><br>The in=
consistency is in some sense hard to evaluate because, as mentioned, the or=
iginal paper did not specify the purpose of to_string(). In many use cases =
such as human readable files using hexfloat might be a fundamental change t=
o usability: for example I would reckon that it's quite different for i=
nteroperability with other tools (spreadsheet etc.) to have a file with %g-=
formatted values compared to hexfloats. And using it is even harder to just=
ify when one can use non-lossy decimal representation. But requiring round-=
tripping might actually be indirect: what if it is not required? What shoul=
d to_string() do? If the suggestion is a lossy precision, the arguments can=
directly address the question why the chosen number of digits can be consi=
dered a "fits for all" choice. Of course round-tripping format do=
es not fit for all, but I considered loss of information much bigger an iss=
ue than having an inconvenience in the output; standard can't make a gu=
arantee that the formatted looks nice and has the right number of digits fo=
r everyone, but it could guarantee some aspects of information preservation=
for everyone.<br><br>hexfloat is by my understanding available through opt=
ions 'a' and 'A'.<br><br><br><div style=3D"margin-left: 40p=
x;">Likelihood of causing breaking changes<br></div><br>Generally speaking =
if a developer has created an application relying on a standard guaranteed =
behaviour, any change can be a breaking one (here for example one could be =
assuming that the result does not contain character 'e'). Especiall=
y the silent runtime behaviour change is potentially hazardous. <br><br><di=
v style=3D"margin-left: 40px;">Use of exceptions<br></div><br>Unfortunately=
the noexcept seems to be out of question due to the potential allocation o=
f std::string. thanks for pointing that out. Why the (direct) use of except=
ions such as std::invalid_argument does not seem appropriate is that it see=
ms a bit too severe a consequence that failing to create a string would in =
practice often crash the application; i.e. people would forget to use try-c=
atch with to_string().=C2=A0 It's not a serious error if conversion fai=
ls as the function can simply report "I got garbage, I can't give =
an answer and you can check this from the return value if interested".=
If the failure is a serious error for the application, it should handle it=
accordingly. But this is more a question of when and why the standard seem=
s appropriate to use exception and how to apply it in this case if this eve=
r proceed to such stage. <br><br><div style=3D"margin-left: 40px;">"Fi=
nally, why does it have to be a new function?"<br></div><br>Because an=
y change is potentially a breaking change; if experienced standard people f=
eel the expected consequences are negligible, personally I would probably u=
se to_string() more happily than to_string_f(). And while "%g" wo=
uld have been better than "%f" in some sense, %g implies only 6 s=
ignificant digits which also has a severe problem:<br><br><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"></span><div class=3D"prettyprint" =
style=3D"background-color: rgb(250, 250, 250); border-color: rgb(187, 187, =
187); border-style: solid; border-width: 1px; word-wrap: break-word;"><code=
class=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"color: =
#000;" class=3D"styled-by-prettify">=C2=A0 =C2=A0 </span><span style=3D"col=
or: #008;" class=3D"styled-by-prettify">const</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #008;" cla=
ss=3D"styled-by-prettify">auto</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"> t </span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">=3D</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"> std</span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
::</span><span style=3D"color: #000;" class=3D"styled-by-prettify">time</sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span =
style=3D"color: #008;" class=3D"styled-by-prettify">nullptr</span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">);</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </span><span sty=
le=3D"color: #008;" class=3D"styled-by-prettify">const</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #=
008;" class=3D"styled-by-prettify">auto</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"> d </span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"> </span><span style=3D"color: #008;" class=3D"styled-by-pr=
ettify">static_cast</span><span style=3D"color: #080;" class=3D"styled-by-p=
rettify"><double></span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy">t</span><span style=3D"color: #660;" class=3D"styled-by-prettify">);</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =
=C2=A0 </span><span style=3D"color: #008;" class=3D"styled-by-prettify">if<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><sp=
an style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify">t </span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">=3D=3D</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"> d</span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">)</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"><br>=C2=A0 =C2=A0 </span><span style=3D"color: #660;" cla=
ss=3D"styled-by-prettify">{</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"colo=
r: #008;" class=3D"styled-by-prettify">char</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"> szBuffer</span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">[</span><span style=3D"color: #066;" class=
=3D"styled-by-prettify">128</span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">];</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 std</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">::</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify">cout </span><span style=3D"color: #660;" class=3D=
"styled-by-prettify"><<</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"> </span><span style=3D"color: #080;" class=3D"styled-by-=
prettify">"Values are identical\n"</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color: #660;" class=3D"styled-by=
-prettify"><<</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"> </span><span style=3D"color: #080;" class=3D"styled-by-prettify">=
"to_string(t) =3D "</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-=
prettify"><<</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"> std</span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">::</span><span style=3D"color: #000;" class=3D"styled-by-prettify">to_str=
ing</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify">t</span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">)</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660=
;" class=3D"styled-by-prettify"><<</span><span style=3D"color: #000;"=
class=3D"styled-by-prettify"> </span><span style=3D"color: #080;" class=3D=
"styled-by-prettify">'\n'</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 </span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
><<</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> =
</span><span style=3D"color: #080;" class=3D"styled-by-prettify">"to_s=
tring(d) =3D "</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
<<</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> s=
td</span><span style=3D"color: #660;" class=3D"styled-by-prettify">::</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify">to_string</span>=
<span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify">d</span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">)</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=
=3D"styled-by-prettify"><<</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: #080;" class=3D"style=
d-by-prettify">'\n'</span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">;</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 sprintf</span><span style=3D"color:=
#660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify">szBuffer</span><span style=3D"color: #660;" cla=
ss=3D"styled-by-prettify">,</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"> </span><span style=3D"color: #080;" class=3D"styled-by-pr=
ettify">"%g"</span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"> d</span><span style=3D"color: #660;" class=3D"styled-by-prettify">);</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =
=C2=A0 =C2=A0 =C2=A0 std</span><span style=3D"color: #660;" class=3D"styled=
-by-prettify">::</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify">cout </span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
><<</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> =
</span><span style=3D"color: #080;" class=3D"styled-by-prettify">"to_s=
tring(d) if %g instead of %f =3D "</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"=
styled-by-prettify"><<</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"> szBuffer </span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify"><<</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify"> </span><span style=3D"color: #080;" class=3D"styled-by-pre=
ttify">'\n'</span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">;</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
<br>=C2=A0 =C2=A0 </span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">}</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><=
br></span></div></code></div><br><br>Example output:<br><div class=3D"prett=
yprint" style=3D"background-color: rgb(250, 250, 250); border-color: rgb(18=
7, 187, 187); border-style: solid; border-width: 1px; word-wrap: break-word=
;"><code class=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D=
"color: #606;" class=3D"styled-by-prettify">Values</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"> are identical<br>to_string</span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify">t</span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">)</span><span style=3D"color: #000;"=
class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"styled=
-by-prettify"> </span><span style=3D"color: #066;" class=3D"styled-by-prett=
ify">1456783429</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"><br>to_string</span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">d=
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">)</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #066;=
" class=3D"styled-by-prettify">1456783429.000000</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"><br>to_string</span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #000=
;" class=3D"styled-by-prettify">d</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">)</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> </span><span style=3D"color: #008;" class=3D"styled-by-pret=
tify">if</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> <=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">%</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify">g instead of </span>=
<span style=3D"color: #660;" class=3D"styled-by-prettify">%</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify">f </span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">=3D</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"> </span><span style=3D"color: #066;" clas=
s=3D"styled-by-prettify">1.45678e+09</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"> </span></div></code></div><br>So with %g identic=
al values would result to fundamentally different strings depending on type=
.. So simply changing %f -> %g might result to loss of precision and seve=
rely break existing code on runtime. And if setting a higher precision to a=
void this, the question is how precise? The proposal would make it easy: it=
's precise enough that there's no need to worry about it.<br></div>=
</div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/47b6a73e-1ead-4536-b2e4-ca00402a2324%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/47b6a73e-1ead-4536-b2e4-ca00402a2324=
%40isocpp.org</a>.<br />
------=_Part_1065_885126106.1456788409596--
------=_Part_1064_1984918039.1456788409595--
.
Author: u97234@gmail.com
Date: Fri, 20 May 2016 06:34:23 -0700 (PDT)
Raw View
------=_Part_2026_1391500960.1463751263283
Content-Type: multipart/alternative;
boundary="----=_Part_2027_1189433374.1463751263283"
------=_Part_2027_1189433374.1463751263283
Content-Type: text/plain; charset=UTF-8
There's now a preliminary proposal draft
<https://drive.google.com/open?id=0B8fu7_MirpvpQURrVzJ5eWdVRHM>available
for comments. It is by no means ready for submit and there are many open
questions the need to be addressed.
A quick summary of current views:
- Default std::to_string() must provide base 10 representation with
round-tripping possibility at least for non-NaN's, NaN's are yet to be
decided.
- std::to_string() has overload for easy formatting similar to
QString::number()
- String format is independent of locales.
- Exact string representation is implementation specific as long as it
fulfils these requirements.
- The way how to change the standard is open: every option evaluated has
major drawbacks.
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/27d1a744-9ace-40f8-85af-f06375d11175%40isocpp.org.
------=_Part_2027_1189433374.1463751263283
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">There's now a <a href=3D"https://drive.google.com/open=
?id=3D0B8fu7_MirpvpQURrVzJ5eWdVRHM">preliminary proposal draft </a>availabl=
e for comments. It is by no means ready for submit and there are many open =
questions the need to be addressed.<br><br>A quick summary of current views=
:<br><ul><li>Default std::to_string() must provide base 10 representation w=
ith round-tripping possibility at least for non-NaN's, NaN's are ye=
t to be decided.</li><li>std::to_string() has overload for easy formatting =
similar to QString::number()</li><li>String format is independent of locale=
s.</li><li>Exact string representation is implementation specific as long a=
s it fulfils these requirements.</li><li>The way how to change the standard=
is open: every option evaluated has major drawbacks.<br></li></ul><br></di=
v>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/27d1a744-9ace-40f8-85af-f06375d11175%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/27d1a744-9ace-40f8-85af-f06375d11175=
%40isocpp.org</a>.<br />
------=_Part_2027_1189433374.1463751263283--
------=_Part_2026_1391500960.1463751263283--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Fri, 20 May 2016 13:36:01 -0700 (PDT)
Raw View
------=_Part_160_611301040.1463776561508
Content-Type: multipart/alternative;
boundary="----=_Part_161_1093810152.1463776561509"
------=_Part_161_1093810152.1463776561509
Content-Type: text/plain; charset=UTF-8
On Friday, May 20, 2016 at 9:34:23 AM UTC-4, u97...@gmail.com wrote:
>
> There's now a preliminary proposal draft
> <https://drive.google.com/open?id=0B8fu7_MirpvpQURrVzJ5eWdVRHM>available
> for comments.
>
It isn't really showing up as HTML in my browser. Or rather, it *is*
showing up as HTML. I can see the tags. Google Drive seems to think it was
a text file.
Also, you seem to have been beaten to the punch by a fairly wide margin.
<http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2016/p0067r1.html>
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/65115604-3edc-4878-89bb-c0b607e92303%40isocpp.org.
------=_Part_161_1093810152.1463776561509
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><br>On Friday, May 20, 2016 at 9:34:23 AM UTC-4, u97..=
..@gmail.com wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;marg=
in-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"=
ltr">There's now a <a href=3D"https://drive.google.com/open?id=3D0B8fu7=
_MirpvpQURrVzJ5eWdVRHM" target=3D"_blank" rel=3D"nofollow" onmousedown=3D"t=
his.href=3D'https://drive.google.com/open?id\x3d0B8fu7_MirpvpQURrVzJ5eW=
dVRHM';return true;" onclick=3D"this.href=3D'https://drive.google.c=
om/open?id\x3d0B8fu7_MirpvpQURrVzJ5eWdVRHM';return true;">preliminary p=
roposal draft </a>available for comments.</div></blockquote><div><br>It isn=
't really showing up as HTML in my browser. Or rather, it <i>is</i> sho=
wing up as HTML. I can see the tags. Google Drive seems to think it was a t=
ext file.<br><br>Also, you seem to have been <a href=3D"http://www.open-std=
..org/JTC1/SC22/WG21/docs/papers/2016/p0067r1.html">beaten to the punch by a=
fairly wide margin.</a></div></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/65115604-3edc-4878-89bb-c0b607e92303%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/65115604-3edc-4878-89bb-c0b607e92303=
%40isocpp.org</a>.<br />
------=_Part_161_1093810152.1463776561509--
------=_Part_160_611301040.1463776561508--
.
Author: u97234@gmail.com
Date: Sat, 21 May 2016 02:10:56 -0700 (PDT)
Raw View
------=_Part_738_1253168689.1463821856787
Content-Type: multipart/alternative;
boundary="----=_Part_739_1506929737.1463821856787"
------=_Part_739_1506929737.1463821856787
Content-Type: text/plain; charset=UTF-8
The file can be viewed correctly by downloading it. Big thanks for point
out P0067; a great proposal addressing the fundamental machinery needed but
it doesn't discuss the future of std::to_string() so these would be
complementary instead of competing.
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/0a5e838a-fae5-4b1c-b277-c857b9f0ac4c%40isocpp.org.
------=_Part_739_1506929737.1463821856787
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">The file can be viewed correctly by downloading it. Big th=
anks for point out P0067; a great proposal addressing the fundamental machi=
nery needed but it doesn't discuss the future of std::to_string() so th=
ese would be complementary instead of competing.<br></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/0a5e838a-fae5-4b1c-b277-c857b9f0ac4c%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/0a5e838a-fae5-4b1c-b277-c857b9f0ac4c=
%40isocpp.org</a>.<br />
------=_Part_739_1506929737.1463821856787--
------=_Part_738_1253168689.1463821856787--
.