211 lines
3.5 KiB
C++
211 lines
3.5 KiB
C++
/*
|
|
* Copyright 2009 Free Software Foundation, Inc.
|
|
*
|
|
* This software is distributed under the terms of the GNU Affero Public License.
|
|
* See the COPYING file in the main directory for details.
|
|
*
|
|
* This use of this software may be subject to additional restrictions.
|
|
* See the LEGAL file in the main directory for details.
|
|
|
|
This program is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU Affero General Public License as published by
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program 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 Affero General Public License for more details.
|
|
|
|
You should have received a copy of the GNU Affero General Public License
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
|
#ifndef F16_H
|
|
#define F16_H
|
|
|
|
#include <stdint.h>
|
|
#include <ostream>
|
|
|
|
|
|
|
|
/** Round a float to the appropriate F16 value. */
|
|
inline int32_t _f16_round(float f)
|
|
{
|
|
if (f>0.0F) return (int32_t)(f+0.5F);
|
|
if (f<0.0F) return (int32_t)(f-0.5F);
|
|
return 0;
|
|
}
|
|
|
|
|
|
|
|
/** A class for F15.16 fixed point arithmetic with saturation. */
|
|
class F16 {
|
|
|
|
|
|
private:
|
|
|
|
int32_t mV;
|
|
|
|
|
|
public:
|
|
|
|
F16() {}
|
|
|
|
F16(int i) { mV = i<<16; }
|
|
F16(float f) { mV = _f16_round(f*65536.0F); }
|
|
F16(double f) { mV = _f16_round((float)f*65536.0F); }
|
|
|
|
int32_t& raw() { return mV; }
|
|
const int32_t& raw() const { return mV; }
|
|
|
|
float f() const { return mV/65536.0F; }
|
|
|
|
//operator float() const { return mV/65536.0F; }
|
|
//operator int() const { return mV>>16; }
|
|
|
|
F16 operator=(float f)
|
|
{
|
|
mV = _f16_round(f*65536.0F);
|
|
return *this;
|
|
}
|
|
|
|
F16 operator=(int i)
|
|
{
|
|
mV = i<<16;
|
|
return *this;
|
|
}
|
|
|
|
F16 operator=(const F16& other)
|
|
{
|
|
mV = other.mV;
|
|
return mV;
|
|
}
|
|
|
|
F16 operator+(const F16& other) const
|
|
{
|
|
F16 retVal;
|
|
retVal.mV = mV + other.mV;
|
|
return retVal;
|
|
}
|
|
|
|
F16& operator+=(const F16& other)
|
|
{
|
|
mV += other.mV;
|
|
return *this;
|
|
}
|
|
|
|
F16 operator-(const F16& other) const
|
|
{
|
|
F16 retVal;
|
|
retVal.mV = mV - other.mV;
|
|
return retVal;
|
|
}
|
|
|
|
F16& operator-=(const F16& other)
|
|
{
|
|
mV -= other.mV;
|
|
return *this;
|
|
}
|
|
|
|
F16 operator*(const F16& other) const
|
|
{
|
|
F16 retVal;
|
|
int64_t p = (int64_t)mV * (int64_t)other.mV;
|
|
retVal.mV = p>>16;
|
|
return retVal;
|
|
}
|
|
|
|
F16& operator*=(const F16& other)
|
|
{
|
|
int64_t p = (int64_t)mV * (int64_t)other.mV;
|
|
mV = p>>16;
|
|
return *this;
|
|
}
|
|
|
|
F16 operator*(float f) const
|
|
{
|
|
F16 retVal;
|
|
retVal.mV = mV * f;
|
|
return retVal;
|
|
}
|
|
|
|
F16& operator*=(float f)
|
|
{
|
|
mV *= f;
|
|
return *this;
|
|
}
|
|
|
|
F16 operator/(const F16& other) const
|
|
{
|
|
F16 retVal;
|
|
int64_t pV = (int64_t)mV << 16;
|
|
retVal.mV = pV / other.mV;
|
|
return retVal;
|
|
}
|
|
|
|
F16& operator/=(const F16& other)
|
|
{
|
|
int64_t pV = (int64_t)mV << 16;
|
|
mV = pV / other.mV;
|
|
return *this;
|
|
}
|
|
|
|
F16 operator/(float f) const
|
|
{
|
|
F16 retVal;
|
|
retVal.mV = mV / f;
|
|
return retVal;
|
|
}
|
|
|
|
F16& operator/=(float f)
|
|
{
|
|
mV /= f;
|
|
return *this;
|
|
}
|
|
|
|
bool operator>(const F16& other) const
|
|
{
|
|
return mV>other.mV;
|
|
}
|
|
|
|
bool operator<(const F16& other) const
|
|
{
|
|
return mV<other.mV;
|
|
}
|
|
|
|
bool operator==(const F16& other) const
|
|
{
|
|
return mV==other.mV;
|
|
}
|
|
|
|
bool operator>(float f) const
|
|
{
|
|
return (mV/65536.0F) > f;
|
|
}
|
|
|
|
bool operator<(float f) const
|
|
{
|
|
return (mV/65536.0F) < f;
|
|
}
|
|
|
|
bool operator==(float f) const
|
|
{
|
|
return (mV/65536.0F) == f;
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
inline std::ostream& operator<<(std::ostream& os, const F16& v)
|
|
{
|
|
os << v.f();
|
|
return os;
|
|
}
|
|
|
|
#endif
|
|
|