Boost.Real  1.0.0
Boost.Real numerical data type for real numbers representation using range arithmetic.
real_algorithm.hpp
1 #ifndef BOOST_REAL_REAL_ALGORITHM_HPP
2 #define BOOST_REAL_REAL_ALGORITHM_HPP
3 
4 #include <real/interval.hpp>
5 
6 namespace boost {
7  namespace real {
8 
20 
21  // Number representation as a function that return the number digits
22  // an integer part and a sign (+/-)
23  int (*_get_nth_digit)(unsigned int);
24  int _exponent;
25  bool _positive;
26 
27  // Precision
28  unsigned int _maximum_precision = 0;
29 
30  public:
31 
32  static unsigned int maximum_precision;
33 
42  private:
43 
44  // Iterator precision
45  int _n = 0;
46 
47  // Internal number to iterate
48  real_algorithm const* _real_ptr = nullptr;
49 
50  void check_and_swap_boundaries() {
51  if (!this->_real_ptr->_positive) {
52  this->approximation_interval.swap_bounds();
53  }
54  }
55 
56  public:
57 
58  // Number approximation_interval boundaries
59  boost::real::interval approximation_interval;
60 
65  const_precision_iterator() = default;
66 
74  const_precision_iterator(const const_precision_iterator& other) = default;
75 
84  explicit const_precision_iterator(real_algorithm const* real_number) : _n(1), _real_ptr(real_number) {
85 
86  this->approximation_interval.lower_bound.exponent = this->_real_ptr->_exponent;
87  this->approximation_interval.upper_bound.exponent = this->_real_ptr->_exponent;
88  this->approximation_interval.lower_bound.positive = this->_real_ptr->_positive;
89  this->approximation_interval.upper_bound.positive = this->_real_ptr->_positive;
90 
91  int first_digit = (*this->_real_ptr)[0];
92  this->approximation_interval.lower_bound.digits.push_back(first_digit);
93 
94  if (first_digit == 10) {
95  this->approximation_interval.upper_bound.digits.push_back(1);
96  this->approximation_interval.upper_bound.exponent++;
97  } else {
98  this->approximation_interval.upper_bound.digits.push_back(first_digit + 1);
99  }
100 
101  this->check_and_swap_boundaries();
102  }
103 
108  void operator++() {
109  this->iterate_n_times(1);
110  }
111 
116  void iterate_n_times(int n) {
117 
118  // If the number is negative, bounds are interpreted as mirrored:
119  // First, the operation is made as positive, and after bound calculation
120  // bounds are swapped to come back to the negative representation.
121  this->check_and_swap_boundaries();
122 
123  for (int i = 0; i < n; i++) {
124  this->approximation_interval.lower_bound.push_back((*this->_real_ptr)[this->_n + i]);
125  }
126 
127  this->approximation_interval.upper_bound.clear();
128  this->approximation_interval.upper_bound.digits.resize(this->approximation_interval.lower_bound.size());
129  int carry = 1;
130  for (int i = (int)this->approximation_interval.lower_bound.size() - 1; i >= 0; --i) {
131  if (this->approximation_interval.lower_bound[i] + carry == 10) {
132  this->approximation_interval.upper_bound[i] = 0;
133  } else {
134  this->approximation_interval.upper_bound[i] = this->approximation_interval.lower_bound[i] + carry;
135  carry = 0;
136  }
137  }
138 
139  if (carry > 0) {
140  this->approximation_interval.upper_bound.push_front(carry);
141  this->approximation_interval.upper_bound.exponent = this->approximation_interval.lower_bound.exponent + 1;
142  } else {
143  this->approximation_interval.upper_bound.exponent = this->approximation_interval.lower_bound.exponent;
144  }
145 
146  // Left normalization of boundaries representation
147  this->approximation_interval.lower_bound.normalize_left();
148  this->approximation_interval.upper_bound.normalize_left();
149 
150  this->check_and_swap_boundaries();
151  this->_n += n;
152  }
153 
161  bool operator==(const const_precision_iterator& other) const {
162  // uninitialized iterators are never equals
163  if (this->_real_ptr == nullptr || other._real_ptr == nullptr) {
164  return false;
165  }
166 
167  return (other._real_ptr == this->_real_ptr) &&
168  (other._n == this->_n) &&
169  (other.approximation_interval == this->approximation_interval);
170  }
171 
178  bool operator!=(const const_precision_iterator& other) const {
179  return !(*this == other);
180  }
181  };
182 
187  real_algorithm() = default;
188 
194  real_algorithm(const real_algorithm& other) = default;
195 
206  explicit real_algorithm(int (*get_nth_digit)(unsigned int), int exponent)
207  : _get_nth_digit(get_nth_digit), _exponent(exponent), _positive(true) {}
208 
222  explicit real_algorithm(int (*get_nth_digit)(unsigned int),
223  int exponent,
224  bool positive)
225  : _get_nth_digit(get_nth_digit),
226  _exponent(exponent),
227  _positive(positive) {}
228 
235  unsigned int max_precision() const {
236  return boost::real::real_algorithm::maximum_precision;
237  }
238 
244  void set_maximum_precision(unsigned int maximum_precision) {
245  this->_maximum_precision = maximum_precision;
246  }
247 
251  int exponent() const {
252  return this->_exponent;
253  }
254 
258  bool positive() const {
259  return this->_positive;
260  }
261 
271  return const_precision_iterator(this);
272  }
273 
283  const_precision_iterator it(this);
284  it.iterate_n_times(boost::real::real_algorithm::maximum_precision - 1);
285  return it;
286  }
287 
294  int operator[](unsigned int n) const { return this->_get_nth_digit(n); }
295 
302  real_algorithm& operator=(const real_algorithm& other) = default;
303  };
304  }
305 }
306 
314 std::ostream& operator<<(std::ostream& os, const boost::real::real_algorithm& r) {
315  auto it = r.cbegin();
316  for (unsigned int i = 0; i <= r.max_precision(); i++) {
317  ++it;
318  }
319  os << it.approximation_interval;
320  return os;
321 }
322 
323 #endif //BOOST_REAL_REAL_ALGORITHM_HPP
const_precision_iterator(real_algorithm const *real_number)
Pointer constructor: Construct a new boost::real::real_algorithm::const_precision_iterator pointing t...
Definition: real_algorithm.hpp:84
unsigned int max_precision() const
Returns the maximum allowed precision, if that precision is reached and an operator need more precisi...
Definition: real_algorithm.hpp:235
Definition: boundary.hpp:7
is a forward iterator that iterates a boost::real::real_algorithm number approximation intervals...
Definition: real_algorithm.hpp:41
int operator[](unsigned int n) const
Returns the n-th digit the number.
Definition: real_algorithm.hpp:294
const_precision_iterator cend() const
Construct a new boost::real::real_algorithm::con_precision_iterator that iterates the number approxim...
Definition: real_algorithm.hpp:282
void clear()
ir clears the number digits.
Definition: boundary.hpp:235
boost::real::real_algorithm is a C++ class that represents real numbers as a a function that calculat...
Definition: real_algorithm.hpp:19
real_algorithm(int(*get_nth_digit)(unsigned int), int exponent)
Lambda function constructor with exponent: Creates a boost::real::real_algorithm instance that repres...
Definition: real_algorithm.hpp:206
void operator++()
It recalculates the approximation interval boundaries increasing the used precision, the new pointed approximation interval is smaller than the current one.
Definition: real_algorithm.hpp:108
real_algorithm()=default
Default constructor: Construct an empty boost::real::real_algorithm with undefined representation and...
Represent an interval composed by two boundaries, a lower boundary and an upper boundary. The boundaries are boost::real::boundary structs that represent fully represented numbers.
Definition: interval.hpp:18
real_algorithm & operator=(const real_algorithm &other)=default
It assign a new copy of the other boost::real::real_algorithm number in the *this boost::real::real_a...
void push_front(int digit)
add the digit parameter as a new digit of the boost::real::boundary. The digit is added in the left s...
Definition: boundary.hpp:196
real_algorithm(int(*get_nth_digit)(unsigned int), int exponent, bool positive)
Lambda function constructor with exponent and sign: Creates a boost::real::real_algorithm instance th...
Definition: real_algorithm.hpp:222
void push_back(int digit)
add the digit parameter as a new digit of the boost::real::boundary. The digit is added in the right ...
Definition: boundary.hpp:186
void set_maximum_precision(unsigned int maximum_precision)
Set a new maximum precision for the instance.
Definition: real_algorithm.hpp:244
bool operator!=(const const_precision_iterator &other) const
It compare by value not equal; two boost::real::real_algorithm::const_precision_iterators.
Definition: real_algorithm.hpp:178
void normalize_left()
Removes extra zeros at the left side to convert the number representation into a semi normalized repr...
Definition: boundary.hpp:225
void iterate_n_times(int n)
It recalculates the approximation interval boundaries increasing the used precision n times...
Definition: real_algorithm.hpp:116
const_precision_iterator()=default
Default constructor: Constructs an empty boost::real::real_algorithm::const_precision_iterator that p...
void swap_bounds()
Swaps the lower boundary with the upper boundary. After this method is called the boost::real::interv...
Definition: interval.hpp:52
int exponent() const
Definition: real_algorithm.hpp:251
bool positive() const
Definition: real_algorithm.hpp:258
unsigned long size()
It return the amount of digit of the boost::real::boundary.
Definition: boundary.hpp:254
bool operator==(const const_precision_iterator &other) const
It compare by value equality; two boost::real::real_algorithm::const_precision_iterators are equals i...
Definition: real_algorithm.hpp:161
const_precision_iterator cbegin() const
Construct a new boost::real::real_algorithm::con_precision_iterator that iterates the number approxim...
Definition: real_algorithm.hpp:270