00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
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>
00040
00041
00042
00043 namespace mln
00044 {
00045
00046 namespace value
00047 {
00048
00049
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
00096
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 }
00147
00148
00149
00150 inline
00151 float01::float01()
00152 : nbits_(0)
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
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
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
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 }
00281
00282 }
00283
00284 # include <mln/value/float01_.hh>
00285
00286 #endif // ! MLN_VALUE_FLOAT01_HH