$extrastylesheet
Olena  User documentation 2.1
An Image Processing Platform
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
float01.hh
1 // Copyright (C) 2006, 2007, 2008, 2009, 2011 EPITA Research and
2 // Development Laboratory (LRDE)
3 //
4 // This file is part of Olena.
5 //
6 // Olena is free software: you can redistribute it and/or modify it under
7 // the terms of the GNU General Public License as published by the Free
8 // Software Foundation, version 2 of the License.
9 //
10 // Olena is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 // General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with Olena. If not, see <http://www.gnu.org/licenses/>.
17 //
18 // As a special exception, you may use this file as part of a free
19 // software project without restriction. Specifically, if other files
20 // instantiate templates or use macros or inline functions from this
21 // file, or you compile this file and link it with other files to produce
22 // an executable, this file does not by itself cause the resulting
23 // executable to be covered by the GNU General Public License. This
24 // exception does not however invalidate any other reasons why the
25 // executable file might be covered by the GNU General Public License.
26 
27 #ifndef MLN_VALUE_FLOAT01_HH
28 # define MLN_VALUE_FLOAT01_HH
29 
33 
34 # include <iostream>
35 # include <utility>
36 
37 # include <mln/core/concept/value.hh>
38 # include <mln/value/concept/floating.hh>
39 # include <mln/trait/value_.hh>
40 # include <mln/trait/all.hh> // FIXME!
41 
42 
43 
44 namespace mln
45 {
46 
47  namespace value
48  {
49 
50  // Fwd decl.
51  template <unsigned n> struct float01_;
52  class float01;
53 
54 
57  class float01 : public Floating<float01>
58  {
59  public:
60 
62  typedef std::pair<unsigned, unsigned long> enc;
63 
65  typedef float equiv;
66 
68  float01();
69 
71  template <unsigned n>
72  float01(const float01_<n>& val);
73 
75  float01(unsigned nbits, float val);
76 
78  float value() const;
79 
81  unsigned long value_ind() const;
82 
84  unsigned nbits() const;
85 
86 
88  float01& set_nbits(unsigned nbits);
89 
91  const float01 to_nbits(unsigned nbits) const;
92 
94  operator float() const;
95 
96 // template <unsigned n>
97 // operator float01_<n>() const;
98 
99  protected:
101  unsigned nbits_;
102 
104  unsigned long val_;
105  };
106 
107  std::ostream& operator<<(std::ostream& ostr, const float01& g);
108 
109  bool operator==(const float01& lhs, const float01& rhs);
110  bool operator<(const float01& lhs, const float01& rhs);
111 
112 
113 
114 # ifndef MLN_INCLUDE_ONLY
115 
116  namespace internal
117  {
118 
119  inline
120  unsigned long two_pow_(unsigned n)
121  {
122  if (n == 0)
123  return 1;
124  else
125  return 2 * two_pow_(n - 1);
126  }
127 
128  inline
129  unsigned long two_pow_n_minus_1(unsigned n)
130  {
131  return two_pow_(n) - 1;
132  }
133 
134  template <unsigned n_dest>
135  inline
136  unsigned long convert(unsigned n_src, unsigned long val)
137  {
138  if (n_dest == n_src)
139  return val;
140  else
141  if (n_dest > n_src)
142  return val * two_pow_n_minus_1(n_dest) / two_pow_n_minus_1(n_src);
143  else
144  return val / two_pow_(n_src - n_dest);
145  }
146 
147  } // end of mln::value::internal
148 
149 
150  // Float01.
151  inline
153  : nbits_(0) // FIXME: Cost at run-time...
154  {
155  }
156 
157  template <unsigned n>
158  inline
159  float01::float01(const float01_<n>& g)
160  : nbits_(n),
161  val_(g.to_enc())
162  {
163  }
164 
165  inline
166  float01::float01(unsigned nbits, float val)
167  : nbits_(nbits)
168  {
169  val_ = static_cast<unsigned long>(val * float(internal::two_pow_n_minus_1(nbits)));
170  }
171 
172  inline
173  float float01::value() const
174  {
175  mln_invariant(nbits_ != 0);
176  return float(val_) / float(internal::two_pow_n_minus_1(nbits_));
177  }
178 
179  inline
180  unsigned long float01::value_ind() const
181  {
182  mln_invariant(nbits_ != 0);
183  return val_;
184  }
185 
186  inline
187  unsigned float01::nbits() const
188  {
189  return nbits_;
190  }
191 
192  inline
193  float01&
194  float01::set_nbits(unsigned nbits)
195  {
196  mln_precondition(nbits != 0);
197  mln_invariant(nbits_ != 0);
198  if (nbits == nbits_)
199  return *this;
200  if (nbits > nbits_)
201  {
202  val_ *= internal::two_pow_n_minus_1(nbits);
203  val_ /= internal::two_pow_n_minus_1(nbits_);
204  }
205  else // nbits < nbits_
206  {
207  val_ /= internal::two_pow_(nbits_ - nbits);
208  }
209  nbits_ = nbits;
210  return *this;
211  }
212 
213  inline
214  const float01
215  float01::to_nbits(unsigned nbits) const
216  {
217  mln_precondition(nbits != 0);
218  mln_invariant(nbits_ != 0);
219  float01 tmp(*this);
220  tmp.set_nbits(nbits);
221  return tmp;
222  }
223 
224  inline
225  float01::operator float() const
226  {
227  mln_precondition(nbits_ != 0);
228  float tmp = float(val_) / float(internal::two_pow_n_minus_1(nbits_));
229  return tmp;
230  }
231 
232 // template <unsigned n>
233 // float01::operator float01_<n>() const
234 // {
235 // mln_precondition(nbits_ != 0);
236 // float01_<n> tmp;
237 // tmp.set_ind(internal::convert<n>(nbits_, val_));
238 // mln_assertion(tmp.value() < internal::two_pow_(n));
239 // return tmp;
240 // }
241 
242 
243  // Operators.
244 
245  inline
246  std::ostream& operator<<(std::ostream& ostr, const float01& g)
247  {
248  return ostr << g.value() << '/' << g.nbits() << "nbits";
249  }
250 
251  inline
252  bool operator==(const float01& lhs, const float01& rhs)
253  {
254  mln_precondition(lhs.nbits() != 0 && rhs.nbits() != 0);
255 
256  if (rhs.nbits() == lhs.nbits())
257  return lhs.value_ind() == rhs.value_ind();
258 
259  if (lhs.nbits() < rhs.nbits())
260  return lhs.value_ind() == rhs.to_nbits(lhs.nbits()).value_ind();
261  else
262  {
263  return lhs.to_nbits(rhs.nbits()).value_ind() == rhs.value_ind();
264  }
265  }
266 
267  inline
268  bool operator<(const float01& lhs, const float01& rhs)
269  {
270  mln_precondition(lhs.nbits() != 0 && rhs.nbits() != 0);
271  if (rhs.nbits() == lhs.nbits())
272  return lhs.value() < rhs.value();
273  if (lhs.nbits() > rhs.nbits())
274  return lhs.value() < rhs.to_nbits(lhs.nbits()).value();
275  else
276  return lhs.to_nbits(rhs.nbits()).value() < rhs.value();
277  }
278 
279 # endif // ! MLN_INCLUDE_ONLY
280 
281  } // end of namespace mln::value
282 
283 } // end of namespace mln
284 
285 # include <mln/value/float01_.hh>
286 
287 #endif // ! MLN_VALUE_FLOAT01_HH