Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Possible error convert bin_float value bigger than unsigned_long_long_max to unsigned long long #652

Open
ckormanyos opened this issue Jan 20, 2025 · 1 comment

Comments

@ckormanyos
Copy link
Member

ckormanyos commented Jan 20, 2025

OK so,

  • You take a number larger than ::std::numeric_limits<unsigned long long>::max() and store this in cpp_bin_float_50.
  • Then you convert that cpp_bin_float_50 value to unsigned long long
  • I find the wrong answers, or what seem to be wrong. I expect to get the max()- value of the integral type.
  • cpp_dec_float_50 gets it right, if that is what right means.
  • Both backends behave properly for signed long long, the signed version of the intger.
#include <boost/multiprecision/cpp_bin_float.hpp>
#include <boost/multiprecision/cpp_dec_float.hpp>

#include <ctime>
#include <iomanip>
#include <iostream>
#include <limits>
#include <random>

template<typename FloatType, typename LongIshType>
auto test() -> void
{
  std::mt19937_64 gen { static_cast<typename std::mt19937_64::result_type>(std::clock()) };

  auto dis =
    std::uniform_real_distribution<float>
    {
      static_cast<float>(1.01F),
      static_cast<float>(1.04F)
    };

  for(auto i = static_cast<unsigned>(UINT8_C(0)); i < static_cast<unsigned>(UINT8_C(8)); ++i)
  {
    static_cast<void>(i);

    using float_type = FloatType;

    using long_type = LongIshType;

    float_type
      flt_max_more
      {
          float_type { (std::numeric_limits<long_type>::max)() }
        * static_cast<float>((static_cast<int>(i) + 1) * 2) * dis(gen)
      };

    const long_type conversion_result_max_more { static_cast<long_type>(flt_max_more) };

    std::stringstream strm { };

    strm << "0x" << std::hex << std::uppercase << conversion_result_max_more;

    std::cout << strm.str() << std::endl;
  }

  std::cout << std::endl;
}

auto main() -> int
{
  test<::boost::multiprecision::cpp_dec_float_50, signed long long>();
  test<::boost::multiprecision::cpp_bin_float_50, signed long long>();

  test<::boost::multiprecision::cpp_dec_float_50, unsigned long long>();
  test<::boost::multiprecision::cpp_bin_float_50, unsigned long long>();
}

I get (the last group is seemingly wrong):

0x7FFFFFFFFFFFFFFF
0x7FFFFFFFFFFFFFFF
0x7FFFFFFFFFFFFFFF
0x7FFFFFFFFFFFFFFF
0x7FFFFFFFFFFFFFFF
0x7FFFFFFFFFFFFFFF
0x7FFFFFFFFFFFFFFF
0x7FFFFFFFFFFFFFFF

0x7FFFFFFFFFFFFFFF
0x7FFFFFFFFFFFFFFF
0x7FFFFFFFFFFFFFFF
0x7FFFFFFFFFFFFFFF
0x7FFFFFFFFFFFFFFF
0x7FFFFFFFFFFFFFFF
0x7FFFFFFFFFFFFFFF
0x7FFFFFFFFFFFFFFF

0xFFFFFFFFFFFFFFFF
0xFFFFFFFFFFFFFFFF
0xFFFFFFFFFFFFFFFF
0xFFFFFFFFFFFFFFFF
0xFFFFFFFFFFFFFFFF
0xFFFFFFFFFFFFFFFF
0xFFFFFFFFFFFFFFFF
0xFFFFFFFFFFFFFFFF

0x72D23FFFFFFFFFD
0xE6E2FFFFFFFFFFB
0x2426E7FFFFFFFFF9
0x15C58FFFFFFFFFF7
0x348C7FFFFFFFFFF5
0x72B5F7FFFFFFFFF3
0x567493FFFFFFFFF1
0x321AFFFFFFFFFFEF
@ckormanyos
Copy link
Member Author

If this is an error, I'm happy to fix it any time soon, since it is actually breaking one of my stress trests for new work right now.

Cc: @jzmaddock

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant