/src/quantlib/ql/math/rounding.hpp
Line | Count | Source |
1 | | /* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ |
2 | | |
3 | | /* |
4 | | Copyright (C) 2004 Decillion Pty(Ltd) |
5 | | |
6 | | This file is part of QuantLib, a free-software/open-source library |
7 | | for financial quantitative analysts and developers - http://quantlib.org/ |
8 | | |
9 | | QuantLib is free software: you can redistribute it and/or modify it |
10 | | under the terms of the QuantLib license. You should have received a |
11 | | copy of the license along with this program; if not, please email |
12 | | <quantlib-dev@lists.sf.net>. The license is also available online at |
13 | | <https://www.quantlib.org/license.shtml>. |
14 | | |
15 | | This program is distributed in the hope that it will be useful, but WITHOUT |
16 | | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
17 | | FOR A PARTICULAR PURPOSE. See the license for more details. |
18 | | */ |
19 | | |
20 | | /*! \file rounding.hpp |
21 | | \brief Rounding implementation |
22 | | */ |
23 | | |
24 | | #ifndef quantlib_rounding_hpp |
25 | | #define quantlib_rounding_hpp |
26 | | |
27 | | #include <ql/types.hpp> |
28 | | |
29 | | namespace QuantLib { |
30 | | |
31 | | /*! A basic rounding class that supports truncating up to 16 decimal places |
32 | | (input precision range in [0,16]) and depends on a precision of rounding number. |
33 | | Note that the class does not validate the input range; supplying an unsupported |
34 | | rounding value may result in undefined behavior. |
35 | | |
36 | | \test the correctness of the returned values is tested by |
37 | | checking them against known good results. |
38 | | */ |
39 | | class Rounding { |
40 | | public: |
41 | | //! rounding methods |
42 | | /*! The rounding methods follow the OMG specification available |
43 | | at <http://www.omg.org/cgi-bin/doc?formal/00-06-29.pdf>. |
44 | | |
45 | | \warning the names of the Floor and Ceiling methods might |
46 | | be misleading. Check the provided reference. |
47 | | */ |
48 | | enum Type { |
49 | | None, /*!< do not round: return the number unmodified */ |
50 | | Up, /*!< the first decimal place past the precision will be |
51 | | rounded up. This differs from the OMG rule which |
52 | | rounds up only if the decimal to be rounded is |
53 | | greater than or equal to the rounding digit */ |
54 | | Down, /*!< all decimal places past the precision will be |
55 | | truncated */ |
56 | | Closest, /*!< the first decimal place past the precision |
57 | | will be rounded up if greater than or equal |
58 | | to the rounding digit; this corresponds to |
59 | | the OMG round-up rule. When the rounding |
60 | | digit is 5, the result will be the one |
61 | | closest to the original number, hence the |
62 | | name. */ |
63 | | Floor, /*!< positive numbers will be rounded up and negative |
64 | | numbers will be rounded down using the OMG round up |
65 | | and round down rules */ |
66 | | Ceiling /*!< positive numbers will be rounded down and negative |
67 | | numbers will be rounded up using the OMG round up |
68 | | and round down rules */ |
69 | | }; |
70 | | //! default constructor |
71 | | /*! Instances built through this constructor don't perform |
72 | | any rounding. |
73 | | */ |
74 | 0 | Rounding() = default; |
75 | | explicit Rounding(Integer precision, |
76 | | Type type = Closest, |
77 | | Integer digit = 5) |
78 | 0 | : precision_(precision), type_(type), digit_(digit) {} |
79 | | //! perform rounding |
80 | | Decimal operator()(Decimal value) const; |
81 | | //! \name Inspectors |
82 | | //@{ |
83 | 0 | Integer precision() const { return precision_; } |
84 | 0 | Type type() const { return type_; } |
85 | 0 | Integer roundingDigit() const { return digit_; } |
86 | | private: |
87 | | Integer precision_; |
88 | | Type type_ = None; |
89 | | Integer digit_; |
90 | | }; |
91 | | |
92 | | |
93 | | //! Up-rounding. |
94 | | class UpRounding : public Rounding { |
95 | | public: |
96 | | explicit UpRounding(Integer precision, |
97 | | Integer digit = 5) |
98 | 0 | : Rounding(precision,Up,digit) {} |
99 | | }; |
100 | | |
101 | | //! Down-rounding. |
102 | | class DownRounding : public Rounding { |
103 | | public: |
104 | | explicit DownRounding(Integer precision, |
105 | | Integer digit = 5) |
106 | 0 | : Rounding(precision,Down,digit) {} |
107 | | }; |
108 | | |
109 | | //! Closest rounding. |
110 | | class ClosestRounding : public Rounding { |
111 | | public: |
112 | | explicit ClosestRounding(Integer precision, |
113 | | Integer digit = 5) |
114 | 0 | : Rounding(precision,Closest,digit) {} |
115 | | }; |
116 | | |
117 | | //! Ceiling truncation. |
118 | | class CeilingTruncation : public Rounding { |
119 | | public: |
120 | | explicit CeilingTruncation(Integer precision, |
121 | | Integer digit = 5) |
122 | 0 | : Rounding(precision,Ceiling,digit) {} |
123 | | }; |
124 | | |
125 | | //! %Floor truncation. |
126 | | class FloorTruncation : public Rounding { |
127 | | public: |
128 | | explicit FloorTruncation(Integer precision, |
129 | | Integer digit = 5) |
130 | 0 | : Rounding(precision,Floor,digit) {} |
131 | | }; |
132 | | |
133 | | } |
134 | | |
135 | | |
136 | | #endif |