Numeric Cast from integer to floating point
Hi,
Quoting the docs for boost::numeric_cast: "There are several situations
where conversions are unsafe: [...] Conversions from floating point types
to integral types."
What about conversions from integral types to floating point types? E.g.
from 64bit int to double.
The following example shows what I mean:
#include <iostream>
#include <cmath>
#include
Changed subject to see if it gets any attention...
Hi, Quoting the docs for boost::numeric_cast: "There are several situations
where conversions are unsafe: [...] Conversions from floating point types to integral types."
What about conversions from integral types to floating point types? E.g.
from 64bit int to double.
The following example shows what I mean:
#include <iostream> #include <cmath> #include
int main() { const uint64_t i = 123445678911188878; std::cout << "i=" << i << std::endl; const double d = i; std::cout << "d=" << std::fixed << d << std::endl; std::cout << "next=" << std::fixed << std::nextafter(d,
std::numeric_limits<double>::max() ) << std::endl;
std::cout << "prev=" << std::fixed << std::nextafter(d, - std::numeric_limits<double>::max()) << std::endl; // I'd expect the following cast to fail const double dd = boost::numeric_cast<double>(i); std::cout <<"dd=" << std::fixed << dd << std::endl;
return 0; }
prints
i=123445678911188878d=123445678911188880.000000next=123445678911188896.00000 0prev=123445678911188864.000000dd=123445678911188880.000000because that integer cannot be represented in double precisionIs there something in Boost to help here?Thanks in advance
2014-09-08 17:53 GMT+04:00
Hi,
Quoting the docs for boost::numeric_cast: "There are several situations where conversions are unsafe: [...] Conversions from floating point types to integral types."
What about conversions from integral types to floating point types? E.g. from 64bit int to double.
The following example shows what I mean:
#include <iostream> #include <cmath> #include
int main() { const uint64_t i = 123445678911188878; std::cout << "i=" << i << std::endl;
const double d = i; std::cout << "d=" << std::fixed << d << std::endl; std::cout << "next=" << std::fixed << std::nextafter(d, std::numeric_limits<double>::max() ) << std::endl; std::cout << "prev=" << std::fixed << std::nextafter(d, -std::numeric_limits<double>::max()) << std::endl;
// I'd expect the following cast to fail const double dd = boost::numeric_cast<double>(i); std::cout <<"dd=" << std::fixed << dd << std::endl;
return 0; }
prints
i=123445678911188878
d=123445678911188880.000000
next=123445678911188896.000000
prev=123445678911188864.000000
dd=123445678911188880.000000
because that integer cannot be represented in double precision
Is there something in Boost to help here?
That's an interesting question. numeric_cast function was designed to
detect positive and negative overflows, not precision loss. Consider the
example:
std::cout << boost::numeric_cast<int>(1.1999); // OK: 1
std::cout << boost::numeric_cast<int>(1e100); // exception: positive
overflow
Your example is related to the first line, where 1.1999 is converted to
int. When uint64_t i = 123445678911188878; is converted to double there is
no positive/negative overflow, there's only a precision loss.
There is no out-of-the-box solution for your problem, but you can try to so
something by your own using the numeric converter (code was not tested):
// See:
http://www.boost.org/doc/libs/1_56_0/libs/numeric/conversion/doc/html/boost_...
template<class Traits> struct precise_converter { typedef typename Traits
::result_type result_type ; typedef typename Traits::argument_type
argument_type ;
static result_type low_level_convert ( argument_type s ) {
const result_type res = static_cast
[Please do not mail me a copy of your followup]
Antony Polukhin
2014-09-08 17:53 GMT+04:00
: [...] because that integer cannot be represented in double precision
Is there something in Boost to help here?
That's an interesting question. numeric_cast function was designed to detect positive and negative overflows, not precision loss.
Robert Ramey's "Safe Numerics" is designed to allow the cast to proceed when no precision is lost and do something else when precision is lost. http://rrsd.com/blincubator.com/bi_library/safe-numerics/?gform_post_id=426 -- "The Direct3D Graphics Pipeline" free book http://tinyurl.com/d3d-pipeline The Computer Graphics Museum http://computergraphicsmuseum.org The Terminals Wiki http://terminals.classiccmp.org Legalize Adulthood! (my blog) http://legalizeadulthood.wordpress.com
From: Boost-users [mailto:boost-users-bounces@lists.boost.org] On Behalf Of dariomt@gmail.com
Sent: 08 September 2014 14:54
To: boost-users@lists.boost.org
Subject: [Boost-users] Numeric Cast from integer to floating point
Hi,
Quoting the docs for boost::numeric_cast: "There are several situations where conversions are unsafe: [...] Conversions from floating point types to integral types."
What about conversions from integral types to floating point types? E.g. from 64bit int to double.
The following example shows what I mean:
#include <iostream>
#include <cmath>
#include
participants (5)
-
Antony Polukhin
-
dariomt
-
dariomt@gmail.com
-
legalize+jeeves@mail.xmission.com
-
Paul A. Bristow