• Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Classes
  • Files
  • File List

float01.hh

00001 // Copyright (C) 2006, 2007, 2008, 2009 EPITA Research and Development Laboratory (LRDE)
00002 //
00003 // This file is part of Olena.
00004 //
00005 // Olena is free software: you can redistribute it and/or modify it under
00006 // the terms of the GNU General Public License as published by the Free
00007 // Software Foundation, version 2 of the License.
00008 //
00009 // Olena is distributed in the hope that it will be useful,
00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012 // General Public License for more details.
00013 //
00014 // You should have received a copy of the GNU General Public License
00015 // along with Olena.  If not, see <http://www.gnu.org/licenses/>.
00016 //
00017 // As a special exception, you may use this file as part of a free
00018 // software project without restriction.  Specifically, if other files
00019 // instantiate templates or use macros or inline functions from this
00020 // file, or you compile this file and link it with other files to produce
00021 // an executable, this file does not by itself cause the resulting
00022 // executable to be covered by the GNU General Public License.  This
00023 // exception does not however invalidate any other reasons why the
00024 // executable file might be covered by the GNU General Public License.
00025 
00026 #ifndef MLN_VALUE_FLOAT01_HH
00027 # define MLN_VALUE_FLOAT01_HH
00028 
00032 
00033 # include <iostream>
00034 # include <utility>
00035 
00036 # include <mln/core/concept/value.hh>
00037 # include <mln/value/concept/floating.hh>
00038 # include <mln/trait/value_.hh>
00039 # include <mln/trait/all.hh> // FIXME!
00040 
00041 
00042 
00043 namespace mln
00044 {
00045 
00046   namespace value
00047   {
00048 
00049     // Fwd decl.
00050     template <unsigned n> class float01_;
00051     class float01;
00052 
00053 
00056     class float01 : public Floating<float01>
00057     {
00058     public:
00059 
00061       typedef std::pair<unsigned, unsigned long> enc;
00062 
00064       typedef float equiv;
00065 
00067       float01();
00068 
00070       template <unsigned n>
00071       float01(const float01_<n>& val);
00072 
00074       float01(unsigned nbits, float val);
00075 
00077       float value() const;
00078 
00080       unsigned long value_ind() const;
00081 
00083       unsigned nbits() const;
00084 
00085 
00087       float01&     set_nbits(unsigned nbits);
00088 
00090       const float01 to_nbits(unsigned nbits) const;
00091 
00093       operator float() const;
00094 
00095 //       template <unsigned n>
00096 //       operator float01_<n>() const;
00097 
00098     protected:
00100       unsigned nbits_;
00101 
00103       unsigned long val_;
00104     };
00105 
00106     std::ostream& operator<<(std::ostream& ostr, const float01& g);
00107 
00108     bool operator==(const float01& lhs, const float01& rhs);
00109     bool operator<(const float01& lhs, const float01& rhs);
00110 
00111 
00112 
00113 # ifndef MLN_INCLUDE_ONLY
00114 
00115     namespace internal
00116     {
00117 
00118       inline
00119       unsigned long two_pow_(unsigned n)
00120       {
00121         if (n == 0)
00122           return 1;
00123         else
00124           return 2 * two_pow_(n - 1);
00125       }
00126 
00127       inline
00128       unsigned long two_pow_n_minus_1(unsigned n)
00129       {
00130           return two_pow_(n) - 1;
00131       }
00132 
00133       template <unsigned n_dest>
00134       inline
00135       unsigned long convert(unsigned n_src, unsigned long val)
00136       {
00137         if (n_dest == n_src)
00138           return val;
00139         else
00140           if (n_dest > n_src)
00141             return val * two_pow_n_minus_1(n_dest) / two_pow_n_minus_1(n_src);
00142           else
00143             return val / two_pow_(n_src - n_dest);
00144       }
00145 
00146     } // end of mln::value::internal
00147 
00148 
00149     // Float01.
00150     inline
00151     float01::float01()
00152       : nbits_(0) // FIXME: Cost at run-time...
00153     {
00154     }
00155 
00156     template <unsigned n>
00157     inline
00158     float01::float01(const float01_<n>& g)
00159       : nbits_(n),
00160         val_(g.to_enc())
00161     {
00162     }
00163 
00164     inline
00165     float01::float01(unsigned nbits, float val)
00166       : nbits_(nbits)
00167     {
00168       val_ = static_cast<unsigned long>(val * float(internal::two_pow_n_minus_1(nbits)));
00169     }
00170 
00171     inline
00172     float float01::value() const
00173     {
00174       mln_invariant(nbits_ != 0);
00175       return float(val_) / float(internal::two_pow_n_minus_1(nbits_));
00176     }
00177 
00178     inline
00179     unsigned long float01::value_ind() const
00180     {
00181       mln_invariant(nbits_ != 0);
00182       return val_;
00183     }
00184 
00185     inline
00186     unsigned float01::nbits() const
00187     {
00188       return nbits_;
00189     }
00190 
00191     inline
00192     float01&
00193     float01::set_nbits(unsigned nbits)
00194     {
00195       mln_precondition(nbits != 0);
00196       mln_invariant(nbits_ != 0);
00197       if (nbits == nbits_)
00198         return *this;
00199       if (nbits > nbits_)
00200         {
00201           val_ *= internal::two_pow_n_minus_1(nbits);
00202           val_ /= internal::two_pow_n_minus_1(nbits_);
00203         }
00204       else // nbits < nbits_
00205         {
00206           val_ /= internal::two_pow_(nbits_ - nbits);
00207         }
00208       nbits_ = nbits;
00209       return *this;
00210     }
00211 
00212     inline
00213     const float01
00214     float01::to_nbits(unsigned nbits) const
00215     {
00216       mln_precondition(nbits != 0);
00217       mln_invariant(nbits_ != 0);
00218       float01 tmp(*this);
00219       tmp.set_nbits(nbits);
00220       return tmp;
00221     }
00222 
00223     inline
00224     float01::operator float() const
00225     {
00226       mln_precondition(nbits_ != 0);
00227       float tmp = float(val_) / float(internal::two_pow_n_minus_1(nbits_));
00228       return tmp;
00229     }
00230 
00231 //     template <unsigned n>
00232 //     float01::operator float01_<n>() const
00233 //     {
00234 //       mln_precondition(nbits_ != 0);
00235 //       float01_<n> tmp;
00236 //       tmp.set_ind(internal::convert<n>(nbits_, val_));
00237 //       mln_assertion(tmp.value() < internal::two_pow_(n));
00238 //       return tmp;
00239 //     }
00240 
00241 
00242     // Operators.
00243 
00244     inline
00245     std::ostream& operator<<(std::ostream& ostr, const float01& g)
00246     {
00247       return ostr << g.value() << '/' << g.nbits() << "nbits";
00248     }
00249 
00250     inline
00251     bool operator==(const float01& lhs, const float01& rhs)
00252     {
00253       mln_precondition(lhs.nbits() != 0 && rhs.nbits() != 0);
00254 
00255       if (rhs.nbits() == lhs.nbits())
00256         return lhs.value_ind() == rhs.value_ind();
00257 
00258       if (lhs.nbits() < rhs.nbits())
00259         return lhs.value_ind() == rhs.to_nbits(lhs.nbits()).value_ind();
00260       else
00261       {
00262         return lhs.to_nbits(rhs.nbits()).value_ind() == rhs.value_ind();
00263       }
00264     }
00265 
00266     inline
00267     bool operator<(const float01& lhs, const float01& rhs)
00268     {
00269       mln_precondition(lhs.nbits() != 0 && rhs.nbits() != 0);
00270       if (rhs.nbits() == lhs.nbits())
00271         return lhs.value() < rhs.value();
00272       if (lhs.nbits() > rhs.nbits())
00273         return lhs.value() < rhs.to_nbits(lhs.nbits()).value();
00274       else
00275         return lhs.to_nbits(rhs.nbits()).value() < rhs.value();
00276     }
00277 
00278 # endif // ! MLN_INCLUDE_ONLY
00279 
00280   } // end of namespace mln::value
00281 
00282 } // end of namespace mln
00283 
00284 # include <mln/value/float01_.hh>
00285 
00286 #endif // ! MLN_VALUE_FLOAT01_HH

Generated on Tue Oct 4 2011 15:23:47 for Milena (Olena) by  doxygen 1.7.1