]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | // Use, modification and distribution are subject to the |
2 | // Boost Software License, Version 1.0. (See accompanying file | |
3 | // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | |
4 | ||
5 | // Copyright Paul A. Bristow 2013 | |
6 | // Copyright Christopher Kormanyos 2013. | |
7 | // Copyright John Maddock 2013. | |
8 | ||
9 | #ifdef _MSC_VER | |
10 | # pragma warning (disable : 4512) | |
11 | # pragma warning (disable : 4996) | |
12 | #endif | |
13 | ||
14 | #define BOOST_TEST_MAIN | |
15 | #define BOOST_LIB_DIAGNOSTIC "on"// Show library file details. | |
16 | ||
17 | #include <boost/test/unit_test.hpp> | |
92f5a8d4 | 18 | #include <boost/test/tools/floating_point_comparison.hpp> // Extra test tool for FP comparison. |
7c673cae FG |
19 | |
20 | #include <iostream> | |
21 | #include <limits> | |
22 | ||
23 | //[expression_template_1 | |
24 | ||
25 | #include <boost/multiprecision/cpp_dec_float.hpp> | |
26 | ||
27 | /*`To define a 50 decimal digit type using `cpp_dec_float`, | |
28 | you must pass two template parameters to `boost::multiprecision::number`. | |
29 | ||
30 | It may be more legible to use a two-staged type definition such as this: | |
31 | ||
32 | `` | |
33 | typedef boost::multiprecision::cpp_dec_float<50> mp_backend; | |
34 | typedef boost::multiprecision::number<mp_backend, boost::multiprecision::et_off> cpp_dec_float_50_noet; | |
35 | `` | |
36 | ||
37 | Here, we first define `mp_backend` as `cpp_dec_float` with 50 digits. | |
38 | The second step passes this backend to `boost::multiprecision::number` | |
39 | with `boost::multiprecision::et_off`, an enumerated type. | |
40 | ||
41 | typedef boost::multiprecision::number<boost::multiprecision::cpp_dec_float<50>, boost::multiprecision::et_off> | |
42 | cpp_dec_float_50_noet; | |
43 | ||
44 | You can reduce typing with a `using` directive `using namespace boost::multiprecision;` | |
45 | if desired, as shown below. | |
46 | */ | |
47 | ||
48 | using namespace boost::multiprecision; | |
49 | ||
50 | ||
51 | /*`Now `cpp_dec_float_50_noet` or `cpp_dec_float_50_et` | |
52 | can be used as a direct replacement for built-in types like `double` etc. | |
53 | */ | |
54 | ||
55 | BOOST_AUTO_TEST_CASE(cpp_float_test_check_close_noet) | |
56 | { // No expression templates/ | |
57 | typedef number<cpp_dec_float<50>, et_off> cpp_dec_float_50_noet; | |
58 | ||
59 | std::cout.precision(std::numeric_limits<cpp_dec_float_50_noet>::digits10); // All significant digits. | |
60 | std::cout << std::showpoint << std::endl; // Show trailing zeros. | |
61 | ||
62 | cpp_dec_float_50_noet a ("1.0"); | |
63 | cpp_dec_float_50_noet b ("1.0"); | |
64 | b += std::numeric_limits<cpp_dec_float_50_noet>::epsilon(); // Increment least significant decimal digit. | |
65 | ||
66 | cpp_dec_float_50_noet eps = std::numeric_limits<cpp_dec_float_50_noet>::epsilon(); | |
67 | ||
68 | std::cout <<"a = " << a << ",\nb = " << b << ",\neps = " << eps << std::endl; | |
69 | ||
70 | BOOST_CHECK_CLOSE(a, b, eps * 100); // Expected to pass (because tolerance is as percent). | |
71 | BOOST_CHECK_CLOSE_FRACTION(a, b, eps); // Expected to pass (because tolerance is as fraction). | |
72 | ||
73 | ||
74 | ||
75 | } // BOOST_AUTO_TEST_CASE(cpp_float_test_check_close) | |
76 | ||
77 | BOOST_AUTO_TEST_CASE(cpp_float_test_check_close_et) | |
78 | { // Using expression templates. | |
79 | typedef number<cpp_dec_float<50>, et_on> cpp_dec_float_50_et; | |
80 | ||
81 | std::cout.precision(std::numeric_limits<cpp_dec_float_50_et>::digits10); // All significant digits. | |
82 | std::cout << std::showpoint << std::endl; // Show trailing zeros. | |
83 | ||
84 | cpp_dec_float_50_et a("1.0"); | |
85 | cpp_dec_float_50_et b("1.0"); | |
86 | b += std::numeric_limits<cpp_dec_float_50_et>::epsilon(); // Increment least significant decimal digit. | |
87 | ||
88 | cpp_dec_float_50_et eps = std::numeric_limits<cpp_dec_float_50_et>::epsilon(); | |
89 | ||
90 | std::cout << "a = " << a << ",\nb = " << b << ",\neps = " << eps << std::endl; | |
91 | ||
92 | BOOST_CHECK_CLOSE(a, b, eps * 100); // Expected to pass (because tolerance is as percent). | |
93 | BOOST_CHECK_CLOSE_FRACTION(a, b, eps); // Expected to pass (because tolerance is as fraction). | |
94 | ||
95 | /*`Using `cpp_dec_float_50` with the default expression template use switched on, | |
96 | the compiler error message for `BOOST_CHECK_CLOSE_FRACTION(a, b, eps); would be: | |
97 | */ | |
98 | // failure floating_point_comparison.hpp(59): error C2440: 'static_cast' : | |
99 | // cannot convert from 'int' to 'boost::multiprecision::detail::expression<tag,Arg1,Arg2,Arg3,Arg4>' | |
100 | //] [/expression_template_1] | |
101 | ||
102 | } // BOOST_AUTO_TEST_CASE(cpp_float_test_check_close) | |
103 | ||
104 | /* | |
105 | ||
106 | Output: | |
107 | ||
108 | Description: Autorun "J:\Cpp\big_number\Debug\test_cpp_float_close_fraction.exe" | |
109 | Running 1 test case... | |
110 | ||
111 | a = 1.0000000000000000000000000000000000000000000000000, | |
112 | b = 1.0000000000000000000000000000000000000000000000001, | |
113 | eps = 1.0000000000000000000000000000000000000000000000000e-49 | |
114 | ||
115 | *** No errors detected | |
116 | ||
117 | ||
118 | */ | |
119 |