/* * This file is part of libgim. * * libgim is free software: you can redistribute it and/or modify it under the * terms of the GNU General Public License as published by the Free Software * Foundation, either version 3 of the License, or (at your option) any later * version. * * libgim is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License * along with libgim. If not, see . * * Copyright 2011-2015 Danny Robson */ #include "fixed.hpp" #include "maths.hpp" #include using namespace util; /////////////////////////////////////////////////////////////////////////////// // Constructors template fixed::fixed (uint_t val): m_value (val << E) { static_assert (I > 0, "must use positive integer bits"); static_assert (E > 0, "must use positive fractional bits"); static_assert (I + E == sizeof (m_value) * 8, "underlying storage must be exactly I+E sized"); } /////////////////////////////////////////////////////////////////////////////// // Conversions template double fixed::to_double (void) const { return static_cast (m_value) / pow (2, E); } //----------------------------------------------------------------------------- template float fixed::to_float (void) const { return static_cast (m_value) / pow (2, E); } //----------------------------------------------------------------------------- template typename fixed::uint_t fixed::to_integral (void) const { return m_value >> E; } //----------------------------------------------------------------------------- template typename fixed::uint_t fixed::to_native (void) const { return m_value; } //----------------------------------------------------------------------------- template fixed fixed::from_native (uint_t i) { return fixed {i}; } //----------------------------------------------------------------------------- template typename fixed::uint_t fixed::to_integral (uint_t v) { return v >> E; } /////////////////////////////////////////////////////////////////////////////// // Integer operators template fixed& fixed::operator+= (uint_t val) { m_value += val << E; return *this; } //----------------------------------------------------------------------------- template fixed& fixed::operator-= (uint_t val) { m_value -= val << E; return *this; } //----------------------------------------------------------------------------- template fixed& fixed::operator*= (uint_t val) { m_value *= val; return *this; } //----------------------------------------------------------------------------- template fixed& fixed::operator/= (uint_t val) { m_value /= val; return *this; } //----------------------------------------------------------------------------- template fixed fixed::operator+ (uint_t val) const { return fixed (m_value + val << E); } //----------------------------------------------------------------------------- template fixed fixed::operator- (uint_t val) const { return fixed (m_value - val << E); } //----------------------------------------------------------------------------- template fixed fixed::operator* (uint_t val) const { return fixed (m_value * val); } //----------------------------------------------------------------------------- template fixed fixed::operator /(uint_t val) const { return fixed (m_value / val); } //----------------------------------------------------------------------------- template class util::fixed<16,16>; template class util::fixed<32,32>; template class util::fixed<26, 6>;