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
00027 #ifndef MLN_VALUE_FLOAT01_HH
00028 # define MLN_VALUE_FLOAT01_HH
00029
00033
00034 # include <iostream>
00035 # include <utility>
00036
00037 # include <mln/core/concept/value.hh>
00038 # include <mln/value/concept/floating.hh>
00039 # include <mln/trait/value_.hh>
00040 # include <mln/trait/all.hh>
00041
00042
00043
00044 namespace mln
00045 {
00046
00047 namespace value
00048 {
00049
00050
00051 template <unsigned n> struct float01_;
00052 class float01;
00053
00054
00057 class float01 : public Floating<float01>
00058 {
00059 public:
00060
00062 typedef std::pair<unsigned, unsigned long> enc;
00063
00065 typedef float equiv;
00066
00068 float01();
00069
00071 template <unsigned n>
00072 float01(const float01_<n>& val);
00073
00075 float01(unsigned nbits, float val);
00076
00078 float value() const;
00079
00081 unsigned long value_ind() const;
00082
00084 unsigned nbits() const;
00085
00086
00088 float01& set_nbits(unsigned nbits);
00089
00091 const float01 to_nbits(unsigned nbits) const;
00092
00094 operator float() const;
00095
00096
00097
00098
00099 protected:
00101 unsigned nbits_;
00102
00104 unsigned long val_;
00105 };
00106
00107 std::ostream& operator<<(std::ostream& ostr, const float01& g);
00108
00109 bool operator==(const float01& lhs, const float01& rhs);
00110 bool operator<(const float01& lhs, const float01& rhs);
00111
00112
00113
00114 # ifndef MLN_INCLUDE_ONLY
00115
00116 namespace internal
00117 {
00118
00119 inline
00120 unsigned long two_pow_(unsigned n)
00121 {
00122 if (n == 0)
00123 return 1;
00124 else
00125 return 2 * two_pow_(n - 1);
00126 }
00127
00128 inline
00129 unsigned long two_pow_n_minus_1(unsigned n)
00130 {
00131 return two_pow_(n) - 1;
00132 }
00133
00134 template <unsigned n_dest>
00135 inline
00136 unsigned long convert(unsigned n_src, unsigned long val)
00137 {
00138 if (n_dest == n_src)
00139 return val;
00140 else
00141 if (n_dest > n_src)
00142 return val * two_pow_n_minus_1(n_dest) / two_pow_n_minus_1(n_src);
00143 else
00144 return val / two_pow_(n_src - n_dest);
00145 }
00146
00147 }
00148
00149
00150
00151 inline
00152 float01::float01()
00153 : nbits_(0)
00154 {
00155 }
00156
00157 template <unsigned n>
00158 inline
00159 float01::float01(const float01_<n>& g)
00160 : nbits_(n),
00161 val_(g.to_enc())
00162 {
00163 }
00164
00165 inline
00166 float01::float01(unsigned nbits, float val)
00167 : nbits_(nbits)
00168 {
00169 val_ = static_cast<unsigned long>(val * float(internal::two_pow_n_minus_1(nbits)));
00170 }
00171
00172 inline
00173 float float01::value() const
00174 {
00175 mln_invariant(nbits_ != 0);
00176 return float(val_) / float(internal::two_pow_n_minus_1(nbits_));
00177 }
00178
00179 inline
00180 unsigned long float01::value_ind() const
00181 {
00182 mln_invariant(nbits_ != 0);
00183 return val_;
00184 }
00185
00186 inline
00187 unsigned float01::nbits() const
00188 {
00189 return nbits_;
00190 }
00191
00192 inline
00193 float01&
00194 float01::set_nbits(unsigned nbits)
00195 {
00196 mln_precondition(nbits != 0);
00197 mln_invariant(nbits_ != 0);
00198 if (nbits == nbits_)
00199 return *this;
00200 if (nbits > nbits_)
00201 {
00202 val_ *= internal::two_pow_n_minus_1(nbits);
00203 val_ /= internal::two_pow_n_minus_1(nbits_);
00204 }
00205 else
00206 {
00207 val_ /= internal::two_pow_(nbits_ - nbits);
00208 }
00209 nbits_ = nbits;
00210 return *this;
00211 }
00212
00213 inline
00214 const float01
00215 float01::to_nbits(unsigned nbits) const
00216 {
00217 mln_precondition(nbits != 0);
00218 mln_invariant(nbits_ != 0);
00219 float01 tmp(*this);
00220 tmp.set_nbits(nbits);
00221 return tmp;
00222 }
00223
00224 inline
00225 float01::operator float() const
00226 {
00227 mln_precondition(nbits_ != 0);
00228 float tmp = float(val_) / float(internal::two_pow_n_minus_1(nbits_));
00229 return tmp;
00230 }
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245 inline
00246 std::ostream& operator<<(std::ostream& ostr, const float01& g)
00247 {
00248 return ostr << g.value() << '/' << g.nbits() << "nbits";
00249 }
00250
00251 inline
00252 bool operator==(const float01& lhs, const float01& rhs)
00253 {
00254 mln_precondition(lhs.nbits() != 0 && rhs.nbits() != 0);
00255
00256 if (rhs.nbits() == lhs.nbits())
00257 return lhs.value_ind() == rhs.value_ind();
00258
00259 if (lhs.nbits() < rhs.nbits())
00260 return lhs.value_ind() == rhs.to_nbits(lhs.nbits()).value_ind();
00261 else
00262 {
00263 return lhs.to_nbits(rhs.nbits()).value_ind() == rhs.value_ind();
00264 }
00265 }
00266
00267 inline
00268 bool operator<(const float01& lhs, const float01& rhs)
00269 {
00270 mln_precondition(lhs.nbits() != 0 && rhs.nbits() != 0);
00271 if (rhs.nbits() == lhs.nbits())
00272 return lhs.value() < rhs.value();
00273 if (lhs.nbits() > rhs.nbits())
00274 return lhs.value() < rhs.to_nbits(lhs.nbits()).value();
00275 else
00276 return lhs.to_nbits(rhs.nbits()).value() < rhs.value();
00277 }
00278
00279 # endif // ! MLN_INCLUDE_ONLY
00280
00281 }
00282
00283 }
00284
00285 # include <mln/value/float01_.hh>
00286
00287 #endif // ! MLN_VALUE_FLOAT01_HH