ずっと昔64ビット長の固定小数点クラスがほしくて、書いたやつ。
今なら、8ビット長の固定小数点クラスなんですかねー。
#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;
}
};