boostorg / boostorg/multiprecision
Potential error read-string overflow/underflow in bin-float?
- Dominant language
- C++
- Stars
- 265
- Forks
- 128
- Avg merge
- 4h 48m
- Merged PRs (30d)
- 2
Description
Hi folks,
Here is an interesting case that I found while doing extreme amounts of enhanced edge-case testing in Multiprecision. There is a reduced (albeit still rather long) test in the code sample below.
The test is intended to read the string input and check the expected non-normal-ness for overflow and underflow. When you read the string that overflows, you sould get `fpclassify(flt_ovf) == FP_INFINITE` and when you read the string that underflows, you should get `fpclassify(flt_und) == FP_ZERO`.
And it works for `cpp_dec_float` and for the newly-created `cpp_double_double`. But these tests fail for `cpp_bin_float`.
I believe the failure is non-bogus and might represent an actual bug or weakness. And it is within the string read of `cpp_bin_float`.
I don't see a real hurry to look into or (if needed) correct this one, we can do that after August and for the next release cycle.
Cc: @jzmaddock and @mborland
```
#include
#include
#include
#include
#include
#include
template auto my_generator_overflow() noexcept -> FloatType;
template auto my_generator_underflow() noexcept -> FloatType;
namespace local
{
template
bool test_edges_ovf_und()
{
using float_type = FloatType;
const float_type flt_ovf = ::my_generator_overflow();
const float_type flt_und = ::my_generator_underflow();
const bool result_ovf_is_ok { (fpclassify(flt_ovf) == FP_INFINITE) && isinf(flt_ovf) };
const bool result_und_is_ok { (fpclassify(flt_und) == FP_ZERO) };
BOOST_TEST(result_ovf_is_ok);
BOOST_TEST(result_und_is_ok);
const bool result_is_ok { (result_ovf_is_ok && result_und_is_ok) };
return result_is_ok;
}
} // namespace local
auto main() -> int
{
{
using dec_float_backend_type = boost::multiprecision::cpp_dec_float<50>;
using dec_float_type = boost::multiprecision::number;
std::cout << "Testing type: " << typeid(dec_float_type).name() << std::endl;
static_cast(local::test_edges_ovf_und());
}
#if 1
{
using bin_float_backend_type = boost::multiprecision::cpp_bin_float<50>;
using bin_float_type = boost::multiprecision::number;
std::cout << "Testing type: " << typeid(bin_float_type).name() << std::endl;
// TBD: This seemingly trivial test fails for cpp_bin_float.
static_cast(local::test_edges_ovf_und());
}
#endif
{
using double_float_type = boost::multiprecision::cpp_double_double;
std::cout << "Testing type: " << typeid(double_float_type).name() << std::endl;
static_cast(local::test_edges_ovf_und());
}
return boost::report_errors();
}
template
static auto
overflow_expval_maker
{
[]()
{
std::stringstream strm { };
using float_type = FloatType;
strm << std::numeric_limits::max_exponent10 + 4;
return strm.str();
}
};
template
static auto
underflow_expval_maker
{
[]()
{
std::stringstream strm { };
using float_type = FloatType;
strm << std::numeric_limits::min_exponent10 - 4;
return strm.str();
}
};
template
auto my_generator_overflow() noexcept -> FloatType
{
using float_type = FloatType;
const float_type flt_ovf("1.23E" + overflow_expval_maker());
const float_type result(flt_ovf);
return result;
}
template
auto my_generator_underflow() noexcept -> FloatType
{
using float_type = FloatType;
float_type flt_und("1.23E" + underflow_expval_maker());
const float_type result(flt_und);
return result;
}
```
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.