Skip to content

Commit 3074148

Browse files
committed
Overhaul rounding mode example
1 parent 72e73ab commit 3074148

File tree

1 file changed

+63
-16
lines changed

1 file changed

+63
-16
lines changed

examples/rounding_mode.cpp

Lines changed: 63 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,86 @@
1-
// Copyright 2024 Matt Borland
1+
// Copyright 2024 - 2025 Matt Borland
22
// Distributed under the Boost Software License, Version 1.0.
33
// https://www.boost.org/LICENSE_1_0.txt
4+
//
5+
// This example demonstrates how to set and get the global rounding mode
6+
// as well as the effects on numerical results
47

5-
#include <boost/decimal.hpp>
6-
#include <cassert>
8+
#include <boost/decimal/decimal32_t.hpp> // For type decimal32_t
9+
#include <boost/decimal/literals.hpp> // For decimal literals
10+
#include <boost/decimal/cfenv.hpp> // For access to the rounding mode functions
11+
#include <boost/decimal/iostream.hpp> // Decimal support to <iostream>
12+
#include <iostream>
13+
14+
void print_rounding_mode(const boost::decimal::rounding_mode current_mode)
15+
{
16+
// All 5 rounding modes are defined by the enum rounding_mode
17+
using boost::decimal::rounding_mode;
18+
19+
switch (current_mode)
20+
{
21+
case rounding_mode::fe_dec_downward:
22+
std::cout << "fe_dec_downward\n";
23+
break;
24+
case rounding_mode::fe_dec_to_nearest:
25+
std::cout << "fe_dec_to_nearest\n";
26+
break;
27+
case rounding_mode::fe_dec_to_nearest_from_zero:
28+
std::cout << "fe_dec_to_nearest_from_zero\n";
29+
break;
30+
case rounding_mode::fe_dec_toward_zero:
31+
std::cout << "fe_dec_toward_zero\n";
32+
break;
33+
case rounding_mode::fe_dec_upward:
34+
std::cout << "fe_dec_upward\n";
35+
break;
36+
}
37+
}
738

839
int main()
940
{
10-
#ifndef BOOST_DECIMAL_NO_CONSTEVAL_DETECTION
41+
// The rounding mode can only be changed at run-time if the compiler supports
42+
// 1. C++20 std::is_constant_evaluated()
43+
// 2. Intrinsics that do the same
44+
// If neither of the above are defined the library defines BOOST_DECIMAL_NO_CONSTEVAL_DETECTION
1145

12-
using namespace boost::decimal::literals;
46+
// The current rounding mode can be queried with boost::decimal::fegetround
47+
const boost::decimal::rounding_mode default_rounding_mode = boost::decimal::fegetround();
48+
std::cout << "The default rounding mode is: ";
49+
print_rounding_mode(default_rounding_mode);
1350

14-
BOOST_DECIMAL_ATTRIBUTE_UNUSED auto default_rounding_mode = boost::decimal::fegetround(); // Default is fe_dec_to_nearest
51+
// To set a new rounding mode use boost::decimal::fesetround
52+
// fesetround returns current mode after updating the global state
53+
//
54+
// If your compiler set defines BOOST_DECIMAL_NO_CONSTEVAL_DETECTION the global state can not be updated,
55+
// so this can be a useful check to make sure that state is what you expect it to be
56+
auto new_rounding_mode = boost::decimal::fesetround(boost::decimal::rounding_mode::fe_dec_upward);
57+
std::cout << "The current rounding mode is: ";
58+
print_rounding_mode(new_rounding_mode);
1559

16-
BOOST_DECIMAL_ATTRIBUTE_UNUSED auto new_rounding_mode = boost::decimal::fesetround(boost::decimal::rounding_mode::fe_dec_upward);
60+
#ifndef BOOST_DECIMAL_NO_CONSTEVAL_DETECTION
1761

18-
assert(default_rounding_mode != new_rounding_mode);
62+
using namespace boost::decimal::literals;
1963

2064
const auto lhs {"5e+50"_DF};
2165
const auto rhs {"4e+40"_DF};
2266

67+
std::cout << "lhs equals: " << lhs << '\n'
68+
<< "rhs equals: " << rhs << '\n';
69+
2370
// With upward rounding the result will be "5.000001e+50"_DF
2471
// Even though the difference in order of magnitude is greater than the precision of the type,
2572
// any addition in this mode will result in at least a one ULP difference
26-
BOOST_DECIMAL_ATTRIBUTE_UNUSED const auto upward_res {lhs + rhs};
27-
assert(upward_res == "5.000001e+50"_DF);
73+
const auto upward_res {lhs + rhs};
74+
std::cout << " Sum with upward rounding: " << upward_res << '\n';
2875

29-
boost::decimal::fesetround(boost::decimal::rounding_mode::fe_dec_downward);
76+
77+
new_rounding_mode = boost::decimal::fesetround(boost::decimal::rounding_mode::fe_dec_downward);
78+
std::cout << "The current rounding mode is: ";
79+
print_rounding_mode(new_rounding_mode);
3080

3181
// Similar to above in the downward rounding mode any subtraction will result in at least a one ULP difference
32-
BOOST_DECIMAL_ATTRIBUTE_UNUSED const auto downward_res {lhs - rhs};
33-
assert(downward_res == "4.999999e+50"_DF);
82+
const auto downward_res {lhs - rhs};
83+
std::cout << "Sum with downward rounding: " << downward_res << '\n';
3484

3585
#endif // BOOST_DECIMAL_NO_CONSTEVAL_DETECTION
36-
37-
return 0;
3886
}
39-

0 commit comments

Comments
 (0)