compute_float32.hpp 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  1. // Copyright 2023 Matt Borland
  2. // Distributed under the Boost Software License, Version 1.0.
  3. // https://www.boost.org/LICENSE_1_0.txt
  4. #ifndef BOOST_CHARCONV_DETAIL_COMPUTE_FLOAT32_HPP
  5. #define BOOST_CHARCONV_DETAIL_COMPUTE_FLOAT32_HPP
  6. #include <boost/charconv/detail/compute_float64.hpp>
  7. #include <limits>
  8. #include <cstdint>
  9. #include <cmath>
  10. namespace boost { namespace charconv { namespace detail {
  11. inline float compute_float32(std::int64_t power, std::uint64_t i, bool negative, bool& success) noexcept
  12. {
  13. const double d = compute_float64(power, i, negative, success);
  14. float return_val;
  15. if (success)
  16. {
  17. // Some compilers (e.g. Intel) will optimize std::isinf to always false depending on compiler flags
  18. //
  19. // From Intel(R) oneAPI DPC++/C++ Compiler 2023.0.0 (2023.0.0.20221201)
  20. // warning: comparison with infinity always evaluates to false in fast floating point modes [-Wtautological-constant-compare]
  21. // if (std::isinf(return_val))
  22. if (d > static_cast<double>((std::numeric_limits<float>::max)()) ||
  23. d < static_cast<double>((std::numeric_limits<float>::lowest)()))
  24. {
  25. return_val = negative ? -HUGE_VALF : HUGE_VALF;
  26. success = false;
  27. }
  28. else
  29. {
  30. return_val = static_cast<float>(d);
  31. }
  32. }
  33. else
  34. {
  35. if (power > 38)
  36. {
  37. return_val = negative ? -HUGE_VALF : HUGE_VALF;
  38. }
  39. else
  40. {
  41. return_val = negative ? -0.0F : 0.0F;
  42. }
  43. }
  44. return return_val;
  45. }
  46. }}} // Namespaces
  47. #endif // BOOST_CHARCONV_DETAIL_COMPUTE_FLOAT32_HPP