Skip to content

Commit 8bb0d16

Browse files
authored
Merge pull request #978 from boostorg/cpp23-float
C++23 Floats
2 parents 481ce0d + 851b357 commit 8bb0d16

File tree

107 files changed

+3244
-1654
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

107 files changed

+3244
-1654
lines changed

Diff for: .drone.star

+5
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,15 @@ windowsglobalimage="cppalliance/dronevs2019"
1616
def main(ctx):
1717

1818
things_to_test = [ "special_fun", "distribution_tests", "mp", "misc", "interpolators", "quadrature", "autodiff", "long-running-tests", "float128_tests" ]
19+
gcc13_things_to_test = [ "special_fun", "distribution_tests", "mp", "misc", "interpolators", "quadrature", "autodiff", "long-running-tests", "float128_tests", "new_floats" ]
1920
sanitizer_test = [ "special_fun", "distribution_tests", "misc", "interpolators", "quadrature", "float128_tests" ]
2021
gnu_5_stds = [ "gnu++14", "c++14" ]
2122
gnu_6_stds = [ "gnu++14", "c++14", "gnu++17", "c++17" ]
2223
clang_6_stds = [ "c++14", "c++17" ]
2324
gnu_9_stds = [ "gnu++14", "c++14", "gnu++17", "c++17", "gnu++2a", "c++2a" ]
2425
clang_10_stds = [ "c++14", "c++17", "c++2a" ]
2526
gnu_non_native = [ "gnu++17" ]
27+
gcc13_stds = [ "c++23" ]
2628

2729
result = []
2830

@@ -59,6 +61,9 @@ def main(ctx):
5961
result.append(linux_cxx("Ubuntu g++ ARM64" + cxx + " " + suite, "g++", packages="g++", buildtype="boost", image="cppalliance/droneubuntu2204:multiarch", arch="arm64", environment={'TOOLSET': 'gcc', 'COMPILER': 'g++', 'CXXSTD': cxx, 'TEST_SUITE': suite, }, globalenv=globalenv))
6062
for cxx in gnu_non_native:
6163
result.append(osx_cxx("M1 Clang " + cxx + " " + suite, "clang++", buildscript="drone", buildtype="boost", xcode_version="14.1", environment={'TOOLSET': 'clang', 'CXXSTD': cxx, 'TEST_SUITE': suite, 'DEFINE': 'BOOST_MATH_NO_REAL_CONCEPT_TESTS,BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS,BOOST_MATH_MULTI_ARCH_CI_RUN', }, globalenv=globalenv))
64+
for suite in gcc13_things_to_test:
65+
for cxx in gcc13_stds:
66+
result.append(linux_cxx("Ubuntu g++-13 " + cxx + " " + suite, "g++-13", packages="g++-13", buildtype="boost", image="cppalliance/droneubuntu2304:1", environment={'TOOLSET': 'gcc', 'COMPILER': 'g++-13', 'CXXSTD': cxx, 'TEST_SUITE': suite, }, globalenv=globalenv))
6267

6368
return result
6469

Diff for: include/boost/math/concepts/real_concept.hpp

+16
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,10 @@
4545
# include <cstdio>
4646
#endif
4747

48+
#if __has_include(<stdfloat>)
49+
# include <stdfloat>
50+
#endif
51+
4852
namespace boost{ namespace math{
4953

5054
namespace concepts
@@ -79,6 +83,12 @@ class real_concept
7983
#ifdef BOOST_MATH_USE_FLOAT128
8084
real_concept(BOOST_MATH_FLOAT128_TYPE c) : m_value(c){}
8185
#endif
86+
#ifdef __STDCPP_FLOAT32_T__
87+
real_concept(std::float32_t c) : m_value(static_cast<real_concept_base_type>(c)){}
88+
#endif
89+
#ifdef __STDCPP_FLOAT64_T__
90+
real_concept(std::float64_t c) : m_value(static_cast<real_concept_base_type>(c)){}
91+
#endif
8292

8393
// Assignment:
8494
real_concept& operator=(char c) { m_value = c; return *this; }
@@ -96,6 +106,12 @@ class real_concept
96106
real_concept& operator=(float c) { m_value = c; return *this; }
97107
real_concept& operator=(double c) { m_value = c; return *this; }
98108
real_concept& operator=(long double c) { m_value = c; return *this; }
109+
#ifdef __STDCPP_FLOAT32_T__
110+
real_concept& operator=(std::float32_t c) { m_value = c; return *this; }
111+
#endif
112+
#ifdef __STDCPP_FLOAT64_T__
113+
real_concept& operator=(std::float64_t c) { m_value = c; return *this; }
114+
#endif
99115

100116
// Access:
101117
real_concept_base_type value()const{ return m_value; }

Diff for: include/boost/math/differentiation/autodiff.hpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -1491,7 +1491,7 @@ fvar<RealType, Order> sqrt(fvar<RealType, Order> const& cr) {
14911491
BOOST_IF_CONSTEXPR (order == 0)
14921492
return fvar<RealType, Order>(*derivatives);
14931493
else {
1494-
root_type numerator = 0.5;
1494+
root_type numerator = root_type(0.5);
14951495
root_type powers = 1;
14961496
#ifndef BOOST_NO_CXX17_IF_CONSTEXPR
14971497
derivatives[1] = numerator / *derivatives;

Diff for: include/boost/math/differentiation/finite_difference.hpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ namespace detail {
153153

154154
const Real eps = (numeric_limits<Real>::epsilon)();
155155
// Error bound ~eps^4/5
156-
Real h = pow(11.25*eps, static_cast<Real>(1) / static_cast<Real>(5));
156+
Real h = pow(Real(11.25)*eps, static_cast<Real>(1) / static_cast<Real>(5));
157157
h = detail::make_xph_representable(x, h);
158158
Real ymth = f(x - 2 * h);
159159
Real yth = f(x + 2 * h);
@@ -222,7 +222,7 @@ namespace detail {
222222
// Mathematica code to get the error:
223223
// Series[(f[x+h]-f[x-h])*(4/5) + (1/5)*(f[x-2*h] - f[x+2*h]) + (4/105)*(f[x+3*h] - f[x-3*h]) + (1/280)*(f[x-4*h] - f[x+4*h]), {h, 0, 9}]
224224
// If we used Kahan summation, we could get the max error down to h^8|f^(9)(x)|/630 + |f(x)|eps/h.
225-
Real h = pow(551.25*eps, static_cast<Real>(1) / static_cast<Real>(9));
225+
Real h = pow(Real(551.25)*eps, static_cast<Real>(1) / static_cast<Real>(9));
226226
h = detail::make_xph_representable(x, h);
227227

228228
Real yh = f(x + h);

Diff for: include/boost/math/differentiation/lanczos_smoothing.hpp

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include <limits> // to nan initialize
1111
#include <vector>
1212
#include <string>
13+
#include <cstdint>
1314
#include <stdexcept>
1415
#include <type_traits>
1516
#include <boost/math/tools/assert.hpp>

Diff for: include/boost/math/distributions/beta.hpp

+16-15
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
// Copyright John Maddock 2006.
44
// Copyright Paul A. Bristow 2006.
5+
// Copyright Matt Borland 2023.
56

67
// Use, modification and distribution are subject to the
78
// Boost Software License, Version 1.0.
@@ -241,7 +242,7 @@ namespace boost
241242
{
242243
return result;
243244
}
244-
return ibeta_inva(beta, x, probability, Policy());
245+
return static_cast<RealType>(ibeta_inva(beta, x, probability, Policy()));
245246
} // RealType find_alpha(beta, a, probability)
246247

247248
static RealType find_beta(
@@ -264,7 +265,7 @@ namespace boost
264265
{
265266
return result;
266267
}
267-
return ibeta_invb(alpha, x, probability, Policy());
268+
return static_cast<RealType>(ibeta_invb(alpha, x, probability, Policy()));
268269
} // RealType find_beta(alpha, x, probability)
269270

270271
private:
@@ -396,7 +397,7 @@ namespace boost
396397
{
397398
if (a == 1)
398399
{
399-
return 1 / beta(a, b);
400+
return static_cast<RealType>(1 / beta(a, b));
400401
}
401402
else if (a < 1)
402403
{
@@ -411,7 +412,7 @@ namespace boost
411412
{
412413
if (b == 1)
413414
{
414-
return 1 / beta(a, b);
415+
return static_cast<RealType>(1 / beta(a, b));
415416
}
416417
else if (b < 1)
417418
{
@@ -423,7 +424,7 @@ namespace boost
423424
}
424425
}
425426

426-
return ibeta_derivative(a, b, x, Policy());
427+
return static_cast<RealType>(ibeta_derivative(a, b, x, Policy()));
427428
} // pdf
428429

429430
template <class RealType, class Policy>
@@ -454,7 +455,7 @@ namespace boost
454455
{
455456
return 1;
456457
}
457-
return ibeta(a, b, x, Policy());
458+
return static_cast<RealType>(ibeta(a, b, x, Policy()));
458459
} // beta cdf
459460

460461
template <class RealType, class Policy>
@@ -481,16 +482,16 @@ namespace boost
481482
}
482483
if (x == 0)
483484
{
484-
return 1;
485+
return RealType(1);
485486
}
486487
else if (x == 1)
487488
{
488-
return 0;
489+
return RealType(0);
489490
}
490491
// Calculate cdf beta using the incomplete beta function.
491492
// Use of ibeta here prevents cancellation errors in calculating
492493
// 1 - x if x is very small, perhaps smaller than machine epsilon.
493-
return ibetac(a, b, x, Policy());
494+
return static_cast<RealType>(ibetac(a, b, x, Policy()));
494495
} // beta cdf
495496

496497
template <class RealType, class Policy>
@@ -519,13 +520,13 @@ namespace boost
519520
// Special cases:
520521
if (p == 0)
521522
{
522-
return 0;
523+
return RealType(0);
523524
}
524525
if (p == 1)
525526
{
526-
return 1;
527+
return RealType(1);
527528
}
528-
return ibeta_inv(a, b, p, static_cast<RealType*>(nullptr), Policy());
529+
return static_cast<RealType>(ibeta_inv(a, b, p, static_cast<RealType*>(nullptr), Policy()));
529530
} // quantile
530531

531532
template <class RealType, class Policy>
@@ -555,14 +556,14 @@ namespace boost
555556
// Special cases:
556557
if(q == 1)
557558
{
558-
return 0;
559+
return RealType(0);
559560
}
560561
if(q == 0)
561562
{
562-
return 1;
563+
return RealType(1);
563564
}
564565

565-
return ibetac_inv(a, b, q, static_cast<RealType*>(nullptr), Policy());
566+
return static_cast<RealType>(ibetac_inv(a, b, q, static_cast<RealType*>(nullptr), Policy()));
566567
} // Quantile Complement
567568

568569
} // namespace math

Diff for: include/boost/math/distributions/cauchy.hpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ RealType cdf_imp(const cauchy_distribution<RealType, Policy>& dist, const RealTy
8181
RealType mx = -fabs((x - location) / scale); // scale is > 0
8282
if(mx > -tools::epsilon<RealType>() / 8)
8383
{ // special case first: x extremely close to location.
84-
return 0.5;
84+
return static_cast<RealType>(0.5f);
8585
}
8686
result = -atan(1 / mx) / constants::pi<RealType>();
8787
return (((x > location) != complement) ? 1 - result : result);

Diff for: include/boost/math/distributions/detail/hypergeometric_pdf.hpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,7 @@ inline T integer_power(const T& x, int ex)
262262
#ifdef __SUNPRO_CC
263263
return pow(x, T(ex));
264264
#else
265-
return pow(x, ex);
265+
return static_cast<T>(pow(x, ex));
266266
#endif
267267
}
268268
template <class T>

Diff for: include/boost/math/distributions/inverse_gaussian.hpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -382,7 +382,7 @@ inline RealType quantile(const inverse_gaussian_distribution<RealType, Policy>&
382382
RealType guess = detail::guess_ig(p, dist.mean(), dist.scale());
383383
using boost::math::tools::max_value;
384384

385-
RealType min = 0.; // Minimum possible value is bottom of range of distribution.
385+
RealType min = static_cast<RealType>(0); // Minimum possible value is bottom of range of distribution.
386386
RealType max = max_value<RealType>();// Maximum possible value is top of range.
387387
// int digits = std::numeric_limits<RealType>::digits; // Maximum possible binary digits accuracy for type T.
388388
// digits used to control how accurate to try to make the result.
@@ -454,7 +454,7 @@ inline RealType quantile(const complemented2_type<inverse_gaussian_distribution<
454454
// Complement.
455455
using boost::math::tools::max_value;
456456

457-
RealType min = 0.; // Minimum possible value is bottom of range of distribution.
457+
RealType min = static_cast<RealType>(0); // Minimum possible value is bottom of range of distribution.
458458
RealType max = max_value<RealType>();// Maximum possible value is top of range.
459459
// int digits = std::numeric_limits<RealType>::digits; // Maximum possible binary digits accuracy for type T.
460460
// digits used to control how accurate to try to make the result.

Diff for: include/boost/math/distributions/skew_normal.hpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -486,7 +486,7 @@ namespace boost{ namespace math{
486486

487487
// 21 elements
488488
static const RealType shapes[] = {
489-
0.0,
489+
static_cast<RealType>(0.0),
490490
static_cast<RealType>(1.000000000000000e-004),
491491
static_cast<RealType>(2.069138081114790e-004),
492492
static_cast<RealType>(4.281332398719396e-004),
@@ -511,7 +511,7 @@ namespace boost{ namespace math{
511511

512512
// 21 elements
513513
static const RealType guess[] = {
514-
0.0,
514+
static_cast<RealType>(0.0),
515515
static_cast<RealType>(5.000050000525391e-005),
516516
static_cast<RealType>(1.500015000148736e-004),
517517
static_cast<RealType>(3.500035000350010e-004),

Diff for: include/boost/math/interpolators/detail/cardinal_cubic_b_spline_detail.hpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,7 @@ cardinal_cubic_b_spline_imp<Real>::cardinal_cubic_b_spline_imp(BidiIterator f, B
225225
// mapsto
226226
// 1 0 -1 | r0
227227
// 0 1 1/2| (r1 - r0)/4
228-
super_diagonal[1] = 0.5;
228+
super_diagonal[1] = static_cast<Real>(0.5);
229229
rhs[1] = (rhs[1] - rhs[0])/4;
230230

231231
// Now do a tridiagonal row reduction the standard way, until just before the last row:

Diff for: include/boost/math/policies/error_handling.hpp

+13-1
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ namespace detail
8282
{
8383

8484
template <class T>
85-
std::string prec_format(const T& val)
85+
inline std::string prec_format(const T& val)
8686
{
8787
typedef typename boost::math::policies::precision<T, boost::math::policies::policy<> >::type prec_type;
8888
std::stringstream ss;
@@ -95,6 +95,18 @@ std::string prec_format(const T& val)
9595
return ss.str();
9696
}
9797

98+
#ifdef BOOST_MATH_USE_CHARCONV_FOR_CONVERSION
99+
100+
template <>
101+
inline std::string prec_format<std::float128_t>(const std::float128_t& val)
102+
{
103+
char buffer[128] {};
104+
const auto r = std::to_chars(buffer, buffer + sizeof(buffer), val);
105+
return std::string(buffer, r.ptr);
106+
}
107+
108+
#endif
109+
98110
inline void replace_all_in_string(std::string& result, const char* what, const char* with)
99111
{
100112
std::string::size_type pos = 0;

Diff for: include/boost/math/quadrature/naive_monte_carlo.hpp

+17-10
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,11 @@
2121
#include <map>
2222
#include <type_traits>
2323
#include <boost/math/policies/error_handling.hpp>
24+
#include <boost/math/special_functions/fpclassify.hpp>
25+
26+
#ifdef BOOST_NAIVE_MONTE_CARLO_DEBUG_FAILURES
27+
# include <iostream>
28+
#endif
2429

2530
namespace boost { namespace math { namespace quadrature {
2631

@@ -45,6 +50,8 @@ class naive_monte_carlo
4550
{
4651
using std::numeric_limits;
4752
using std::sqrt;
53+
using boost::math::isinf;
54+
4855
uint64_t n = bounds.size();
4956
m_lbs.resize(n);
5057
m_dxs.resize(n);
@@ -58,9 +65,9 @@ class naive_monte_carlo
5865
boost::math::policies::raise_domain_error(function, "The upper bound is <= the lower bound.\n", bounds[i].second, Policy());
5966
return;
6067
}
61-
if (bounds[i].first == -numeric_limits<Real>::infinity())
68+
if (isinf(bounds[i].first))
6269
{
63-
if (bounds[i].second == numeric_limits<Real>::infinity())
70+
if (isinf(bounds[i].second))
6471
{
6572
m_limit_types[i] = detail::limit_classification::DOUBLE_INFINITE;
6673
}
@@ -72,7 +79,7 @@ class naive_monte_carlo
7279
m_dxs[i] = numeric_limits<Real>::quiet_NaN();
7380
}
7481
}
75-
else if (bounds[i].second == numeric_limits<Real>::infinity())
82+
else if (isinf(bounds[i].second))
7683
{
7784
m_limit_types[i] = detail::limit_classification::UPPER_BOUND_INFINITE;
7885
if (singular)
@@ -285,17 +292,17 @@ class naive_monte_carlo
285292
m_done = false;
286293

287294
#ifdef BOOST_NAIVE_MONTE_CARLO_DEBUG_FAILURES
288-
std::cout << "Failed to achieve required tolerance first time through..\n";
289-
std::cout << " variance = " << m_variance << std::endl;
290-
std::cout << " average = " << m_avg << std::endl;
291-
std::cout << " total calls = " << m_total_calls << std::endl;
295+
std::cerr << "Failed to achieve required tolerance first time through..\n";
296+
std::cerr << " variance = " << m_variance << std::endl;
297+
std::cerr << " average = " << m_avg << std::endl;
298+
std::cerr << " total calls = " << m_total_calls << std::endl;
292299

293300
for (std::size_t i = 0; i < m_num_threads; ++i)
294-
std::cout << " thread_calls[" << i << "] = " << m_thread_calls[i] << std::endl;
301+
std::cerr << " thread_calls[" << i << "] = " << m_thread_calls[i] << std::endl;
295302
for (std::size_t i = 0; i < m_num_threads; ++i)
296-
std::cout << " thread_averages[" << i << "] = " << m_thread_averages[i] << std::endl;
303+
std::cerr << " thread_averages[" << i << "] = " << m_thread_averages[i] << std::endl;
297304
for (std::size_t i = 0; i < m_num_threads; ++i)
298-
std::cout << " thread_Ss[" << i << "] = " << m_thread_Ss[i] << std::endl;
305+
std::cerr << " thread_Ss[" << i << "] = " << m_thread_Ss[i] << std::endl;
299306
#endif
300307
}
301308

Diff for: include/boost/math/special_functions/bessel_prime.hpp

+3-3
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,9 @@ inline T cyl_bessel_j_prime_imp(T v, T x, const Policy& pol)
3838
if (x == 0)
3939
{
4040
if (v == 1)
41-
return 0.5;
41+
return static_cast<T>(0.5);
4242
else if (v == -1)
43-
return -0.5;
43+
return static_cast<T>(-0.5);
4444
else if (floor(v) == v || v > 1)
4545
return 0;
4646
else return boost::math::policies::raise_domain_error<T>(
@@ -126,7 +126,7 @@ inline T cyl_bessel_i_prime_imp(T v, T x, const Policy& pol)
126126
if (x == 0)
127127
{
128128
if (v == 1 || v == -1)
129-
return 0.5;
129+
return static_cast<T>(0.5);
130130
else if (floor(v) == v || v > 1)
131131
return 0;
132132
else return boost::math::policies::raise_domain_error<T>(

0 commit comments

Comments
 (0)