On 3/12/17 4:49 AM, John Maddock via Boost wrote:
It's fairly common to see in floating point code, something like:
int integer_part = my_float; double fractional_part = my_float - integer_part;
which is of course pretty seriously unsafe :(
Casting to a safe<int> to ensure there is no overflow would simplify a lot of error checking code.
how so?
BTW for the record, Boost.Math uses itrunc/ltrunc/lltrunc for this operation which throws when the float is too large for the target type. Lots of ways to tackle this, I just wanted you to be aware that there are genuine use cases where float-interoperability is useful and needed.
I've never doubt this. The main thing here is that I wanted to keep the scope of the library small enough to actually do. Treatment of safe<float> is likely a whole 'nuther thing - perhaps even more inticate than dealing int, unsigned int. I thought integers would be simple, the project started out with just an afternoon's work. I've long forgotten what I wanted/needed for. It metasized to what it is today. But as we see, I haven't been able to just ignore floating point. So we'll have to address it at least as it interacts with integers.
I guess there are several possible solutions:
Policies: we have 3 levels of checks: * Permissive, allow all conversions from float and truncate (as long as the truncated value is in range). * Strict, only allow conversion from in-range integral values. Values with fractional parts throw. * Never: static assert on any attempt to convert from float.
An alternative is to use external functions, lets say we have:
template
safe<I> safe_trunc(F f); Which throws only when the truncated value is out of range. Likewise we would need safe_round, safe_floor and safe_ceil. Obviously a certain amount of "bike shed colouring" may be required on those names ;)
we're experts on that subject here a bike shed central