// 固定小数をクラスにしてみた。
#include <iostream>
#include <cmath>
#include <cassert>
#include <limits>
#ifdef NDEBUG
#define check(exp)
#else
#define check(exp) if (!(exp)) { \
std::cerr << __FILE__ << "(" << __LINE__ << "): " << \
#exp << std::endl; \
}
#endif
///////////////////////////////////////////////////////////////////////////////
// fixed<t_shift>
///////////////////////////////////////////////////////////////////////////////
template <unsigned int t_shift>
struct fixed {
int m_value;
fixed() {
}
fixed(const fixed<t_shift>& f) {
m_value = f.m_value;
}
fixed(int i) {
m_value = i << t_shift;
}
fixed(float f) {
m_value = (int)(f * (1 << t_shift));
}
~fixed() { }
bool operator!() const {
return m_value == 0;
}
int get_mask() const {
return ((1 << t_shift) - 1);
}
int get_int_part() const {
return m_value >> t_shift;
}
void set_int_part(int i) {
m_value = (i << t_shift) | (m_value & get_mask());
}
int get_decimal_part() const {
return m_value & get_mask();
}
void set_decimal_part(int part) const {
const int mask = get_mask();
m_value = (m_value & ~mask) | (part & mask);
}
float get_float() const {
return (float)m_value / (float)(1 << t_shift);
}
void set_float(float f) {
m_value = (int)(f * (1 << t_shift));
}
bool operator==(const fixed<t_shift>& f) const {
return m_value == f.m_value;
}
bool operator!=(const fixed<t_shift>& f) const {
return m_value != f.m_value;
}
bool operator<=(const fixed<t_shift>& f) const {
return m_value <= f.m_value;
}
bool operator>=(const fixed<t_shift>& f) const {
return m_value >= f.m_value;
}
bool operator<(const fixed<t_shift>& f) const {
return m_value < f.m_value;
}
bool operator>(const fixed<t_shift>& f) const {
return m_value > f.m_value;
}
bool operator==(int i) const {
return m_value == (i << t_shift);
}
bool operator!=(int i) const {
return m_value != (i << t_shift);
}
bool operator<=(int i) const {
return m_value <= (i << t_shift);
}
bool operator>=(int i) const {
return m_value >= (i << t_shift);
}
bool operator<(int i) const {
return m_value < (i << t_shift);
}
bool operator>(int i) const {
return m_value > (i << t_shift);
}
bool operator==(float f) const {
return m_value == (int)(f * (1 << t_shift));
}
bool operator!=(float f) const {
return m_value != (int)(f * (1 << t_shift));
}
bool operator<=(float f) const {
return m_value <= (int)(f * (1 << t_shift));
}
bool operator>=(float f) const {
return m_value >= (int)(f * (1 << t_shift));
}
bool operator<(float f) const {
return m_value < (int)(f * (1 << t_shift));
}
bool operator>(float f) const {
return m_value > (int)(f * (1 << t_shift));
}
fixed<t_shift>& operator=(const fixed<t_shift>& f) {
m_value = f.m_value;
return *this;
}
fixed<t_shift>& operator=(int i) {
m_value = i << t_shift;
return *this;
}
fixed<t_shift>& operator=(float f) {
m_value = (int)(f * (1 << t_shift));
return *this;
}
fixed<t_shift>& operator+=(const fixed<t_shift>& f) {
m_value += f.m_value;
return *this;
}
fixed<t_shift>& operator-=(const fixed<t_shift>& f) {
m_value -= f.m_value;
return *this;
}
fixed<t_shift>& operator*=(const fixed<t_shift>& f) {
m_value *= f.m_value;
m_value >>= t_shift;
return *this;
}
fixed<t_shift>& operator/=(const fixed<t_shift>& f) {
assert(f.m_value != 0);
m_value <<= t_shift;
m_value /= f.m_value;
return *this;
}
fixed<t_shift>& operator+=(int i) {
m_value += i << t_shift;
return *this;
}
fixed<t_shift>& operator-=(int i) {
m_value -= i << t_shift;
return *this;
}
fixed<t_shift>& operator*=(int i) {
m_value *= i;
return *this;
}
fixed<t_shift>& operator/=(int i) {
assert(i != 0);
m_value /= i;
return *this;
}
fixed<t_shift>& operator<<=(int i) {
m_value <<= i;
return *this;
}
fixed<t_shift>& operator>>=(int i) {
m_value >>= i;
return *this;
}
fixed<t_shift>& operator+=(float f) {
m_value += (int)(f * (1 << t_shift));
return *this;
}
fixed<t_shift>& operator-=(float f) {
m_value -= (int)(f * (1 << t_shift));
return *this;
}
fixed<t_shift>& operator*=(float f) {
m_value = (int)(m_value * f);
return *this;
}
fixed<t_shift>& operator/=(float f) {
assert(f != 0);
m_value = (int)(m_value / f);
return *this;
}
friend inline fixed<t_shift> operator+(const fixed<t_shift>& f1, int i) {
fixed<t_shift> f(f1);
f += i;
return f;
}
friend inline fixed<t_shift> operator-(const fixed<t_shift>& f1, int i) {
fixed<t_shift> f(f1);
f -= i;
return f;
}
friend inline fixed<t_shift> operator*(const fixed<t_shift>& f1, int i) {
fixed<t_shift> f(f1);
f *= i;
return f;
}
friend inline fixed<t_shift> operator/(const fixed<t_shift>& f1, int i) {
fixed<t_shift> f(f1);
f /= i;
return f;
}
friend inline fixed<t_shift> operator+(
const fixed<t_shift>& f1, const fixed<t_shift>& f2)
{
fixed<t_shift> f(f1);
f += f2;
return f;
}
friend inline fixed<t_shift> operator-(
const fixed<t_shift>& f1, const fixed<t_shift>& f2)
{
fixed<t_shift> f(f1);
f -= f2;
return f;
}
friend inline fixed<t_shift> operator*(
const fixed<t_shift>& f1, const fixed<t_shift>& f2)
{
fixed<t_shift> f(f1);
f *= f2;
return f;
}
friend inline fixed<t_shift> operator/(
const fixed<t_shift>& f1, const fixed<t_shift>& f2)
{
fixed<t_shift> f(f1);
f /= f2;
return f;
}
friend inline fixed<t_shift> operator<<(const fixed<t_shift>& f1, int i) {
fixed<t_shift> f(f1);
f <<= i;
return f;
}
friend inline fixed<t_shift> operator>>(const fixed<t_shift>& f1, int i) {
fixed<t_shift> f(f1);
f >>= i;
return f;
}
};
template <unsigned int t_shift>
std::ostream&
operator<<(std::ostream& o, const fixed<t_shift>& f) {
return (o << f.get_float());
}
///////////////////////////////////////////////////////////////////////////////
#ifdef __BORLANDC__
#pragma option -w-8027
#endif
int main(void)
{
fixed<8> f1(1.2f), f2(3.4f), f;
int i = 3;
f = f1 + i;
std::cout << "1.2 + 3 = " << f << std::endl;
f = f1 - i;
std::cout << "1.2 - 3 = " << f << std::endl;
f = f1 * i;
std::cout << "1.2 * 3 = " << f << std::endl;
f = f1 / i;
std::cout << "1.2 / 3 = " << f << std::endl;
f = f1 + f2;
std::cout << "1.2 + 3.4 = " << f << std::endl;
f = f1 - f2;
std::cout << "1.2 - 3.4 = " << f << std::endl;
f = f1 * f2;
std::cout << "1.2 * 3.4 = " << f << std::endl;
f = f1 / f2;
std::cout << "1.2 / 3.4 = " << f << std::endl;
f = 1.2f;
f += 2;
std::cout << "1.2 + 2 = " << f << std::endl;
f = 1.2f;
f -= 2;
std::cout << "1.2 - 2 = " << f << std::endl;
f = 1.2f;
f *= 2;
std::cout << "1.2 * 2 = " << f << std::endl;
f = 1.2f;
f /= 2;
std::cout << "1.2 / 2 = " << f << std::endl;
return 0;
}