#pragma once /*! @file fixed_float.hpp @brief 固定精度浮動小数点クラス・ヘッダ */ #include <boost/assert.hpp> #include <boost/operators.hpp> #include <limits> //! 64ビット長固定精度浮動小数点クラス class fixed64 : private boost::addable<fixed64>, private boost::subtractable<fixed64>, private boost::multipliable<fixed64>, private boost::dividable<fixed64>, private boost::equivalent<fixed64>, private boost::partially_ordered<fixed64> { public: static const int exponent_ = 16; //!< 指数部長 private: int64_t value_; //!< 値 public: //! コンストラクタ inline fixed64() : value_() {} //! コンストラクタ inline explicit fixed64( int64_t value //!< [in] 値 ) : value_(value << exponent_) { BOOST_ASSERT( value <= (std::numeric_limits<int64_t>::max() >> exponent_) ); BOOST_ASSERT( (std::numeric_limits<int64_t>::min() >> exponent_) <= value ); } //! コンストラクタ inline explicit fixed64( double value //!< [in] 値 // ) : value_(static_cast<int64_t>(value * (1LU << exponent_))) { ) : value_(static_cast<int64_t>(value * pow(2.0,exponent_))) { //BOOST_ASSERT( value <= (static_cast<double>(std::numeric_limits<int64_t>::max() >> exponent_) ); //BOOST_ASSERT( (static_cast<double>(std::numeric_limits<int64_t>::min()) >> exponent_) <= value ); } //! コピーコンストラクタ inline fixed64( const fixed64& value //!< [in] 値 ) : value_(value.value_) {} //! オペレータ += inline fixed64& operator += (const fixed64& rhs) { value_ += rhs.value_; return *this; } //! オペレータ -= inline fixed64& operator -= (const fixed64& rhs) { value_ -= rhs.value_; return *this; } //! オペレータ *= inline fixed64& operator *= (const fixed64& rhs) { value_ = static_cast<int64_t>( ( ( ((static_cast<int64_t>(value_)) * (static_cast<int64_t>(rhs.value_))) // 切り上げを行う //& pow( 2.0, exponent_ - 1 ) ) >> exponent_ ) ); return *this; } //! オペレータ /= inline fixed64& operator /= (const fixed64& rhs) { value_ = static_cast<int64_t>( (static_cast<int64_t>(value_) << exponent_) / static_cast<int64_t>(rhs.value_) ); return *this; } //! オペレータ = inline fixed64& operator = (const fixed64& rhs) { value_ = rhs.value_; return *this; } //! オペレータ == inline bool operator == (const fixed64& rhs) const { return value_ == rhs.value_; } //! オペレータ < inline bool operator < (const fixed64& rhs) const { return value_ < rhs.value_; } inline double get(){ return static_cast<double>(value_ / pow(2.0, exponent_)); } inline operator double() const { //return double(value_ * (1 >> exponent_)) ; return double(value_ / pow(2.0, exponent_)); //return double(value_ * (static_cast<int64_t>(1) >> exponent_)) ; } //! オペレータ = inline fixed64& operator = (const double& rhs) { value_ = static_cast<int64_t>(rhs * pow(2.0, exponent_)); return *this; } };
2016年6月16日木曜日
固定小数点クラス
ずっと昔64ビット長の固定小数点クラスがほしくて、書いたやつ。
今なら、8ビット長の固定小数点クラスなんですかねー。
登録:
コメントの投稿 (Atom)
1 件のコメント:
operator double()の実装、return std::ldexp(value, -exponent_)とするともっと簡単だと思います。逆に、doubleから変換するほうもfrexp関数が使えるはずですが、こちらはもう少し面倒そうです。
コメントを投稿