Monday, July 21, 2014

C++ fixed-point type

Simple implementation ...
Preferably, please copy the code into your source editor. (UPDATE: My apology, because there was an error ... -- It's been fixed .. > <)

Output:
Addition
[PASS]    5.0+3.0=8.0F Out: (float) (fixed)  8  8.0000
[PASS]    5.0+=3.0=>8.0F Out: (float) (fixed)  8  8.0000
[PASS]    7.0+-3.0=4.0F Out: (float) (fixed)  4  4.0000
[PASS]    7.0+=-3.0=>4.0F Out: (float) (fixed)  4  4.0000
[PASS]    2.0+-8.0=-6.0F Out: (float) (fixed)  -6  -6.0000
[PASS]    2.0+=-8.0=>-6.0F Out: (float) (fixed)  -6  -6.0000
[PASS]    -6.0+-3.0=-9.0F Out: (float) (fixed)  -9  -9.0000
[PASS]    -6.0+=-3.0=>-9.0F Out: (float) (fixed)  -9  -9.0000

Subtraction
[PASS]    8.0-6.0=2.0F Out: (float) (fixed)  2  2.0000
[PASS]    8.0-=6.0=>2.0F Out: (float) (fixed)  2  2.0000
[PASS]    1.0--3.0=4.0F Out: (float) (fixed)  4  4.0000
[PASS]    1.0-=-3.0=>4.0F Out: (float) (fixed)  4  4.0000
[PASS]    -3.0--9.0=6.0F Out: (float) (fixed)  6  6.0000
[PASS]    -3.0-=-9.0=>6.0F Out: (float) (fixed)  6  6.0000
[PASS]    -2.0-5.0=-7.0F Out: (float) (fixed)  -7  -7.0000
[PASS]    -2.0-=5.0=>-7.0F Out: (float) (fixed)  -7  -7.0000

Multiplication
[PASS]    2.0*3.0=6.0F Out: (float) (fixed)  6  6.0000
[PASS]    2.0*=3.0=>6.0F Out: (float) (fixed)  6  6.0000
[PASS]    3.0*-4.0=-12.0F Out: (float) (fixed)  -12  -12.0000
[PASS]    3.0*=-4.0=>-12.0F Out: (float) (fixed)  -12  -12.0000
[PASS]    2.0*-5.0=-10.0F Out: (float) (fixed)  -10  -10.0000
[PASS]    2.0*=-5.0=>-10.0F Out: (float) (fixed)  -10  -10.0000
[PASS]    -6.0*-7.0=42.0F Out: (float) (fixed)  42  42.0000
[PASS]    -6.0*=-7.0=>42.0F Out: (float) (fixed)  42  42.0000

Division
[PASS]    14.0/3.5=4.0F Out: (float) (fixed)  4  4.0000
[PASS]    14.0/=3.5=>4.0F Out: (float) (fixed)  4  4.0000
[PASS]    15.0/-3.0=-5.0F Out: (float) (fixed)  -5  -5.0000
[PASS]    15.0/=-3.0=>-5.0F Out: (float) (fixed)  -5  -5.0000
[PASS]    -36.0/8.0=-4.5F Out: (float) (fixed)  -4.5  -4.5000
[PASS]    -36.0/=8.0=>-4.5F Out: (float) (fixed)  -4.5  -4.5000
[PASS]    -48.0/-8.0=6.0F Out: (float) (fixed)  6  6.0000
[PASS]    -48.0/=-8.0=>6.0F Out: (float) (fixed)  6  6.0000

Modulo
[PASS]    3.0%5.0=3.0F Out: (float) (fixed)  3  3.0000
[PASS]    2.0%4.5=2.0F Out: (float) (fixed)  2  2.0000
[PASS]    6.5%5.0=1.5F Out: (float) (fixed)  1.5  1.5000
[PASS]    8.0%4.5=3.5F Out: (float) (fixed)  3.5  3.5000


Code:
/*
Other header #1
*/
/*Bloody C99 keywords, I deny!*/
#include<stdint.h>
typedef uint8_t t1u;
typedef int8_t t1s;
typedef uint16_t t2u;
typedef int16_t t2s;
typedef uint32_t t4u;
typedef int32_t t4s;typedef float t4f;
typedef uint64_t t8u;
typedef int64_t t8s;typedef double t8f;

/*Haters gonna hate ... */
typedef void v;
#define ig else if
#define ih else
#define rK noexcept
#define rU const noexcept

/*
Other header #2
*/
typedef t4s tII4;
/*struct tII4{};*/  /*Or something similar*/
/*
Other header #3
*/
typedef t4u tWU4;
/*struct tWU4{};*/  /*Or something similar*/

/*
The header
*/
#include<iostream>
struct tRX4{
public:
typedef t4s tCn;
typedef t4u tFc;
static tFc const cFc=8;
static tCn const cFM=(1<<cFc)-1;
static tRX4 const c0;
static tRX4 const c1;
protected:
tCn m;
public:
inline tCn g()rU{return m;}

v operator+=(tRX4 const&p)rK{m+=p.m;}tRX4 operator+(tRX4 const&p)rU{tRX4 l;l.m=m+p.m;return l;}
v operator-=(tRX4 const&p)rK{m-=p.m;}tRX4 operator-(tRX4 const&p)rU{tRX4 l;l.m=m-p.m;return l;}tRX4 operator-()rU{tRX4 l;l.m=-m;return l;}
inline v operator*=(tRX4 const&p)rK{m=(((t8s)m)*p.m)>>cFc;}inline tRX4 operator*(tRX4 const&p)rU{tRX4 l;l.m=(tCn)((((t8s)m)*p.m)>>cFc);return l;}
inline v operator/=(tRX4 const&p)rK{m=(((t8s)m)<<cFc)/p.m;}inline tRX4 operator/(tRX4 const&p)rU{tRX4 l;l.m=(tCn)((((t8s)m)<<cFc)/p.m);return l;}
inline tRX4 operator%(tRX4 const&p)rU{tRX4 l;l.m=m%p.m;return l;}
inline v operator=(tII4 p)rK{m=(tCn)((t4s)p<<cFc);}
inline v operator*=(tII4 p)rK{m*=(t4s)p;}inline tRX4 operator*(tII4 p)rU{tRX4 l;l.m=m*(t4s)p;return l;}
inline v operator/=(tII4 p)rK{m/=(t4s)p;}inline tRX4 operator/(tII4 p)rU{tRX4 l;l.m=m/(t4s)p;return l;}
inline v operator%=(tII4 p)rK{m%=(t4s)p<<cFc;}inline tRX4 operator%(tII4 p)rU{tRX4 l;l.m=m%((t4s)p<<cFc);return l;}
inline v operator^=(tRX4 const&p)rK{m^=p.m;}inline tRX4 operator^(tRX4 const&p)rU{tRX4 l;l.m=m^p.m;return l;}
inline v operator&=(tRX4 const&p)rK{m&=p.m;}inline tRX4 operator&(tRX4 const&p)rU{tRX4 l;l.m=m&p.m;return l;}
inline v operator|=(tRX4 const&p)rK{m|=p.m;}inline tRX4 operator|(tRX4 const&p)rU{tRX4 l;l.m=m|p.m;return l;}
inline tRX4 operator~()rU{tRX4 l;l.m=~m;return l;}
bool operator==(tRX4 const&p)rU{return m==p.m;}bool operator<=(tRX4 const&p)rU{return m<=p.m;}bool operator<(tRX4 const&p)rU{return m<p.m;}
bool operator!=(tRX4 const&p)rU{return m!=p.m;}bool operator>=(tRX4 const&p)rU{return m>=p.m;}bool operator>(tRX4 const&p)rU{return m>p.m;}
bool operator==(t4f p)rU{return (*this)==tRX4(p);}bool operator<=(t4f p)rU{return (*this)<=tRX4(p);}bool operator<(t4f p)rU{return (*this)<tRX4(p);}
bool operator!=(t4f p)rU{return (*this)!=tRX4(p);}bool operator>=(t4f p)rU{return (*this)>=tRX4(p);}bool operator>(t4f p)rU{return (*this)>tRX4(p);}
friend bool operator==(t4f p,tRX4 const&q)rK{return tRX4(p)==q;}friend bool operator<=(t4f p,tRX4 const&q)rK{return tRX4(p)<=q;}friend bool operator<(t4f p,tRX4 const&q)rK{return tRX4(p)<q;}
friend bool operator!=(t4f p,tRX4 const&q)rK{return tRX4(p)!=q;}friend bool operator>=(t4f p,tRX4 const&q)rK{return tRX4(p)>=q;}friend bool operator>(t4f p,tRX4 const&q)rK{return tRX4(p)>q;}
bool operator==(t8f p)rU{return (*this)==tRX4(p);}bool operator<=(t8f p)rU{return (*this)<=tRX4(p);}bool operator<(t8f p)rU{return (*this)<tRX4(p);}
bool operator!=(t8f p)rU{return (*this)!=tRX4(p);}bool operator>=(t8f p)rU{return (*this)>=tRX4(p);}bool operator>(t8f p)rU{return (*this)>tRX4(p);}
friend bool operator==(t8f p,tRX4 const&q)rK{return tRX4(p)==q;}friend bool operator<=(t8f p,tRX4 const&q)rK{return tRX4(p)<=q;}friend bool operator<(t8f p,tRX4 const&q)rK{return tRX4(p)<q;}
friend bool operator!=(t8f p,tRX4 const&q)rK{return tRX4(p)!=q;}friend bool operator>=(t8f p,tRX4 const&q)rK{return tRX4(p)>=q;}friend bool operator>(t8f p,tRX4 const&q)rK{return tRX4(p)>q;}

friend std::ostream&operator<<(std::ostream&,tRX4 const&)rK;

public:
inline v operator=(t4f p)rK{m=(tCn)(p*c1.m);}
inline v operator=(t8f p)rK{m=(tCn)(p*c1.m);}
inline tRX4(t4f p)rK{m=(tCn)(p*c1.m);}
inline tRX4(t8f p)rK{m=(tCn)(p*c1.m);}
public:
inline explicit tRX4(t2s p,t2u q)rK:m((((tCn)p)<<cFc)|(q>>(16-cFc))){}
inline explicit tRX4(tII4 const&p)rK{m=(tCn)((t4s)p<<cFc);}
inline explicit tRX4(tWU4 const&p)rK{m=(tCn)((t4u)p<<cFc);}
public:
tRX4&operator=(tRX4 const&)rK=default;
tRX4&operator=(tRX4&&)rK=default;
tRX4(tRX4 const&)rK=default;
tRX4(tRX4&&)rK=default;
tRX4()rK=default;};

/*
The source
*/
tRX4 const tRX4::c0(tII4(0));
tRX4 const tRX4::c1(tII4(1));

std::ostream&operator<<(std::ostream&q,tRX4 const&p)rK{tRX4::tCn l;if(p<tRX4::c0){l=~p.g()+1;if(l>0){q<<"-";}}ih{l=p.g();}
static tRX4::tCn const l10=1000;
tRX4::tCn const lDm=((l&(tRX4::c1.g()-1))*l10*10)/tRX4::c1.g();
tRX4::tCn lDv=l10;
q<<(l>>tRX4::cFc);q<<".";
while(lDv&&!(lDm/lDv)){q<<"0";lDv/=10;}if(lDm){q<<lDm;}return q;}

/*
The tester
*/
#include<cmath>

v f()rK{
#define o_f1(a,b,p1,p2,p)\
lA1=a,lA2=b;lA0=lA1 p1 lA2;\
lB1=a,lB2=b;lB0=lB1 p1 lB2;\
std::cout<<(lB0==p?"[PASS]":"[FAIL]")<<"    "<<#a<<#p1<<#b<<"="<<#p<<" Out: (float) (fixed)  "<<lA0<<"  "<<lB0<<std::endl;\
lA0=a,lA1=b;lA0 p2 lA1;\
lB0=a,lB1=b;lB0 p2 lB1;\
std::cout<<(lB0==p?"[PASS]":"[FAIL]")<<"    "<<#a<<#p2<<#b<<"=>"<<#p<<" Out: (float) (fixed)  "<<lA0<<"  "<<lB0<<std::endl;
t4f lA0,lA1,lA2;
tRX4 lB0,lB1,lB2,lB3;
printf("Addition\n");
o_f1(5.0,3.0,+,+=,8.0F)
o_f1(7.0,-3.0,+,+=,4.0F)
o_f1(2.0,-8.0,+,+=,-6.0F)
o_f1(-6.0,-3.0,+,+=,-9.0F)printf("\n");
printf("Subtraction\n");
o_f1(8.0,6.0,-,-=,2.0F)
o_f1(1.0,-3.0,-,-=,4.0F)
o_f1(-3.0,-9.0,-,-=,6.0F)
o_f1(-2.0,5.0,-,-=,-7.0F)printf("\n");
printf("Multiplication\n");
o_f1(2.0,3.0,*,*=,6.0F)
o_f1(3.0,-4.0,*,*=,-12.0F)
o_f1(2.0,-5.0,*,*=,-10.0F)
o_f1(-6.0,-7.0,*,*=,42.0F)printf("\n");
printf("Division\n");
o_f1(14.0,3.5,/,/=,4.0F)
o_f1(15.0,-3.0,/,/=,-5.0F)
o_f1(-36.0,8.0,/,/=,-4.5F)
o_f1(-48.0,-8.0,/,/=,6.0F)printf("\n");
#define o_f2(a,b,p1,p)\
lA1=a,lA2=b;lA0=std::fmod(lA1,lA2);\
lB1=a,lB2=b;lB0=lB1 p1 lB2;\
std::cout<<(lB0==p?"[PASS]":"[FAIL]")<<"    "<<#a<<#p1<<#b<<"="<<#p<<" Out: (float) (fixed)  "<<lA0<<"  "<<lB0<<std::endl;
printf("Modulo\n");
o_f2(3.0,5.0,%,3.0F)
o_f2(2.0,4.5,%,2.0F)
o_f2(6.5,5.0,%,1.5F)
o_f2(8.0,4.5,%,3.5F)printf("\n");
#undef o_f2
#undef o_f1
}

int main(){f();getchar();return 0;}

No comments:

Post a Comment