|
| 1 | +// Copyright 2025 Matt Borland |
| 2 | +// Distributed under the Boost Software License, Version 1.0. |
| 3 | +// https://www.boost.org/LICENSE_1_0.txt |
| 4 | +// |
| 5 | +// This file demonstrates how to convert various types to decimal types and back, |
| 6 | +// along with edge case handling |
| 7 | + |
| 8 | +#include <boost/decimal/decimal32_t.hpp> // For type decimal32_t |
| 9 | +#include <boost/decimal/decimal64_t.hpp> // For type decimal64_t |
| 10 | +#include <boost/decimal/cmath.hpp> // For decimal support of cmath functions |
| 11 | +#include <boost/decimal/iostream.hpp> // For decimal support of <iostream> and <iomanip> |
| 12 | +#include <boost/decimal/numbers.hpp> // For decimal support of <numbers> |
| 13 | +#include <iostream> |
| 14 | +#include <limits> |
| 15 | +#include <cstdint> |
| 16 | + |
| 17 | +int main() |
| 18 | +{ |
| 19 | + using boost::decimal::decimal32_t; // Type decimal32_t |
| 20 | + using boost::decimal::decimal64_t; // Type decimal64_t |
| 21 | + |
| 22 | + // Non-finite values construct std::numeric_limits<TargetIntegerType>::max() |
| 23 | + constexpr decimal64_t decimal_qnan {std::numeric_limits<decimal64_t>::quiet_NaN()}; |
| 24 | + const std::uint32_t int_from_nan {static_cast<std::uint32_t>(decimal_qnan)}; |
| 25 | + |
| 26 | + // Note here that we must use boost::decimal::isnan for decimal types, |
| 27 | + // as it is illegal to overload std::isnan |
| 28 | + if (boost::decimal::isnan(decimal_qnan) && int_from_nan == std::numeric_limits<std::uint32_t>::max()) |
| 29 | + { |
| 30 | + std::cout << "Decimal QNAN converts to Integer Max\n"; |
| 31 | + } |
| 32 | + |
| 33 | + // Same thing happens with decimal infinities since integers don't have an infinity |
| 34 | + constexpr decimal32_t decimal_inf {std::numeric_limits<decimal32_t>::infinity()}; |
| 35 | + const std::uint64_t int_from_inf {static_cast<std::uint64_t>(decimal_inf)}; |
| 36 | + |
| 37 | + // Same as the above but with INF instead of NAN |
| 38 | + if (boost::decimal::isinf(decimal_inf) && int_from_inf == std::numeric_limits<std::uint64_t>::max()) |
| 39 | + { |
| 40 | + std::cout << "Decimal INF converts to Integer Max\n"; |
| 41 | + } |
| 42 | + |
| 43 | + // For finite values the construction of the resulting integer matches the behavior |
| 44 | + // you are familiar with from binary floating point to integer conversions. |
| 45 | + // Namely, the result will only have the integer component of the decimal |
| 46 | + |
| 47 | + // Construct the decimal64_t version of pi using our pre-computed constants from <boost/decimal/numbers.hpp> |
| 48 | + constexpr decimal64_t decimal_pi {boost::decimal::numbers::pi_v<decimal64_t>}; |
| 49 | + const std::uint32_t int_from_pi {static_cast<std::uint32_t>(decimal_pi)}; |
| 50 | + |
| 51 | + std::cout << std::setprecision(std::numeric_limits<decimal64_t>::digits10) |
| 52 | + << " decimal64_t pi: " << decimal_pi << '\n' |
| 53 | + << "std::uint32_t pi: " << int_from_pi << "\n\n"; |
| 54 | + |
| 55 | + // Constructing a decimal value from an integer is lossless until |
| 56 | + // the number of digits in the integer exceeds the precision of the decimal type |
| 57 | + |
| 58 | + std::cout << "Conversions will be lossless\n" |
| 59 | + << " decimal64_t digits10: " << std::numeric_limits<decimal64_t>::digits10 << "\n" |
| 60 | + << "std::uint32_t digits10: " << std::numeric_limits<std::uint32_t>::digits10 << "\n"; |
| 61 | + |
| 62 | + constexpr decimal64_t decimal_from_u32_max {std::numeric_limits<std::uint32_t>::max()}; |
| 63 | + std::cout << " std::uint32_t max: " << std::numeric_limits<std::uint32_t>::max() << "\n" |
| 64 | + << "decimal64_t from max: " << decimal_from_u32_max << "\n\n"; |
| 65 | + |
| 66 | + // In the construction of lossy values the rounding will be handled according to |
| 67 | + // the current global rounding mode. |
| 68 | + |
| 69 | + std::cout << "Conversions will be lossy\n" |
| 70 | + << " decimal32_t digits10: " << std::numeric_limits<decimal32_t>::digits10 << "\n" |
| 71 | + << "std::uint64_t digits10: " << std::numeric_limits<std::uint64_t>::digits10 << "\n"; |
| 72 | + |
| 73 | + constexpr decimal32_t decimal_from_u64_max {std::numeric_limits<std::uint64_t>::max()}; |
| 74 | + std::cout << " std::uint64_t max: " << std::numeric_limits<std::uint64_t>::max() << "\n" |
| 75 | + << "decimal32_t from max: " << decimal_from_u64_max << '\n'; |
| 76 | + |
| 77 | + return 0; |
| 78 | +} |
0 commit comments