[lexical_cast] Assumed internal double conversion of float?

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

[lexical_cast] Assumed internal double conversion of float?

Boost - Dev mailing list
Hi Boost experts,
We are chasing down some test failures with floats on VxWorks using the
Dinkum clib and c++lib.
We are testing with clang on Intel and Arm targets and GCC on PowerPC
targets.
An example failure at the bottom of this email.

We have determined that  boost::detail::lcast_get_precision<float>() is
returning 9, well in access of the defined  FLT_DIG of 6, or the practical
float limit of  6.92.

Specifically this code here:

  bool shl_real_type(float val, char* begin) {
                using namespace std;
                const double val_as_double = val;
                finish = start +
#if defined(_MSC_VER) && (_MSC_VER >= 1400) && !defined(__SGI_STL_PORT) &&
!defined(_STLPORT_VERSION)
                    sprintf_s(begin, CharacterBufferSize,
#else
                    sprintf(begin,
#endif
                    "%.*g",
static_cast<int>(boost::detail::lcast_get_precision<float>()),
val_as_double);
                return finish > start;
            }

Where does boost::detail::lcast_get_precision<float>() come from, and why
is it 9 ?
Is it perhaps assuming some intermediate double conversion internally?

In Dinkum's C library, Plager conservatively does not promote to a double,
when converting to a string.

Many thanks,

Brian
Wind River




->cmd
"LD_LIBRARY_PATH=/opt/TestTriggerLocalPath/Workspace/vx7-boost/2019-01-13/vsb/app/boost/fsl_imx6_llvm_up_32_vxWorks/usr/root/llvm/bin;/opt/TestTriggerLocalPath/Workspace/vx7-boost/2019-01-13/vsb/app/boost/fsl_imx6_llvm_up_32_vxWorks/usr/lib/common"
[vxWorks *]# cd
/opt/TestTriggerLocalPath/Workspace/vx7-boost/2019-01-13/vsb/app/boost/fsl_imx6_llvm_up_32_vxWorks/3pp/BOOST/boost_1_68_0/status

[vxWorks *]# run -x -t 0x01000000 -u 100000 --
../bin.v2/libs/lexical_cast/test/lexical_cast_float_types_test.test/clang-vxworks/debug/cross-compile-vxworks/static-only-on/lexical_cast_float_types_test.vxe

Launching process
'../bin.v2/libs/lexical_cast/test/lexical_cast_float_types_test.test/clang-vxworks/debug/cross-compile-vxworks/static-only-on/lexical_cast_float_types_test.vxe'
...
Process
'../bin.v2/libs/lexical_cast/test/lexical_cast_float_types_test.test/clang-vxworks/debug/cross-compile-vxworks/static-only-on/lexical_cast_float_types_test.vxe'
(process Id = 0x20482f10) launched.
Running 3 test cases...
unknown location(0): [4;31;49mfatal error: in "lexical_cast float types
unit test/test_conversion_from_to_double":
boost::exception_detail::clone_impl<boost::exception_detail::error_info_injector<boost::bad_lexical_cast>
>: bad lexical cast: source type value could not be interpreted as target
[0;39;49m
../libs/lexical_cast/test/lexical_cast_float_types_test.cpp(299):
[1;36;49mlast checkpoint [0;39;49m
unknown location(0): [4;31;49mfatal error: in "lexical_cast float types
unit test/test_conversion_from_to_long_double":
boost::exception_detail::clone_impl<boost::exception_detail::error_info_injector<boost::bad_lexical_cast>
>: bad lexical cast: source type value could not be interpreted as target
[0;39;49m
../libs/lexical_cast/test/lexical_cast_float_types_test.cpp(299):
[1;36;49mlast checkpoint [0;39;49m

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: [lexical_cast] Assumed internal double conversion of float?

Boost - Dev mailing list
Brian Kuhl wrote:

> Where does boost::detail::lcast_get_precision<float>() come from, and why
> is it 9 ?
> Is it perhaps assuming some intermediate double conversion internally?

boost::detail::lcast_get_precision<double>() is 17, so no.

My guess is that this is the precision that guarantees a perfect roundtrip.


_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: [lexical_cast] Assumed internal double conversion of float?

Boost - Dev mailing list
Note that there are two numbers of digits that are of interest:

If you take a decimal number, convert it to float, and convert it back to decimal, how many decimal digits are guaranteed to survive unchanged?

If you take a float, convert it to decimal, and convert it back to float, how many decimal digits are required to always get all bits of the original float correct?

For 32-bit float, the answers are 6 and 9, respectively. For 64-bit double, it's 15 and 17.

See: https://www.exploringbinary.com/number-of-digits-required-for-round-trip-conversions/

As an aside: when converting a string to a floating-point number, it is incorrect to round twice - i.e. you cannot implement strtof by calling strtod and then rounding double to float.

STL

-----Original Message-----
From: Boost <[hidden email]> On Behalf Of Peter Dimov via Boost
Sent: Tuesday, January 29, 2019 9:42 AM
To: [hidden email]
Cc: Peter Dimov <[hidden email]>
Subject: Re: [boost] [lexical_cast] Assumed internal double conversion of float?

Brian Kuhl wrote:

> Where does boost::detail::lcast_get_precision<float>() come from, and
> why is it 9 ?
> Is it perhaps assuming some intermediate double conversion internally?

boost::detail::lcast_get_precision<double>() is 17, so no.

My guess is that this is the precision that guarantees a perfect roundtrip.


_______________________________________________
Unsubscribe & other changes: https://nam06.safelinks.protection.outlook.com/?url=http%3A%2F%2Flists.boost.org%2Fmailman%2Flistinfo.cgi%2Fboost&amp;data=02%7C01%7Cstl%40exchange.microsoft.com%7Ce8d933dc57634660657d08d686112ef9%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636843805695126880&amp;sdata=mXgKJMlGxrXod%2BSb8A3HX4F1rFByOZNGZnN4NpeII3w%3D&amp;reserved=0

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: [lexical_cast] Assumed internal double conversion of float?

Boost - Dev mailing list
In reply to this post by Boost - Dev mailing list
> -----Original Message-----
> From: Boost [mailto:[hidden email]] On Behalf Of Brian Kuhl via Boost
> Sent: 29 January 2019 17:28
> To: [hidden email]
> Cc: Brian Kuhl; [hidden email]
> Subject: [boost] [lexical_cast] Assumed internal double conversion of float?
>
> Hi Boost experts,
> We are chasing down some test failures with floats on VxWorks using the
> Dinkum clib and c++lib.
> We are testing with clang on Intel and Arm targets and GCC on PowerPC
> targets.
> An example failure at the bottom of this email.
>
> We have determined that  boost::detail::lcast_get_precision<float>() is
> returning 9, well in access of the defined  FLT_DIG of 6, or the practical
> float limit of  6.92.

It returns std::numeric_limits<float>::maxdigits_10 = 9

This is maximum number of decimal digits that can contain information.  Any more are just noise.

std::numeric_limits<float>::digits_10 = 6

This is the number of decimal digits that are certain to be correct.

The other 3 digits are 'noisy'.

Our ancestors should have just used their fingers, and not their thumbs  ;-)

HTH

Paul

---
Paul A. Bristow
Prizet Farmhouse
Kendal UK LA8 8AB
+44 (0) 1539 561830





_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost