// #define Debug
typedef unsigned char *u8p;
typedef unsigned char u8;
typedef char *s8p;
typedef char s8;
typedef unsigned short int *u16p;
typedef unsigned short int u16;
typedef short int *s16p;
typedef short int s16;
typedef unsigned int *u32p;
typedef unsigned int u32;
typedef int *s32p;
typedef int s32;
typedef float f32;
typedef f32 *f32p;
typedef double f64;
typedef double *f64p;
#ifdef __GNUC__
#define int64 long long
#else /* MSVC */
#define int64 __int64
#pragma warning(disable: 4996)
#endif
typedef signed int64 s64;
typedef unsigned int64 u64;
typedef s64 *s64p;
typedef u64 *u64p;
typedef f64 *f64p;
typedef void (* call_v_v )();
typedef void (* call_v_uS )( u16 ); // void, unsigned Short
typedef void (* call_v_LLB )( u32, u32, u8 ); // void, Long, Long, Byte
typedef u32 (* call_L_L )( u32 ); // Long, Long
typedef u16 (* call_S_L )( u32 ); // Short, Long
typedef u8 (* call_B_L )( u32 ); // Byte, Long
union _u16{
struct{
u8 L, U;
};
u16 X;
};
union _u32{
struct{
_u16 L, U;
};
_u32 & operator=( const u32 nv ){
X = nv;
return *this;
}
u32 X;
u8 bit( u8 x ){ return (X>>x)|1; }
};
union _u64{
struct{
_u32 L, U;
};
u64 X;
u32 gU(){ return *(u32p)&U; }
u32 gL(){ return *(u32p)&L; }
u8 bit( u8 x ){
if( x>=32 ) return U.bit( x-32 );
return L.bit( x );
}
};
struct _u128{
_u64 L, U;
u8 bit( u8 x ){
if( x>=64 ) return U.bit( x-64 );
return L.bit( x );
}
};
typedef u8 *_u8p;
typedef _u16 *_u16p;
typedef _u32 *_u32p;
typedef _u64 *_u64p;
typedef _u128 *_u128p;
struct F32{
u32 X;
F32(){}
F32( int x ){
(*(_u32p)&X).U.X = x;
(*(_u32p)&X).L.X = 0;
}
F32( float x ){
x *= 65536.0f;
X = (u32) x;
}
F32 operator++( void ){
(*(_u32p)&X).U.X++;
return *this;
}
F32 operator++( int ){
(*(_u32p)&X).U.X++;
return *this;
}
F32 operator+=( int x ){
(*(_u32p)&X).U.X+=x;
return *this;
}
F32 operator+=( float x ){
X+=(u32)(x*65536.0f);
return *this;
}
F32 operator+=( F32 x ){
X+=x.X;
return *this;
}
F32 operator--( void ){
(*(_u32p)&X).U.X--;
return *this;
}
F32 operator--( int ){
(*(_u32p)&X).U.X--;
return *this;
}
F32 operator-=( int x){
(*(_u32p)&X).U.X-=x;
return *this;
}
F32 operator=( int x ){
(*(_u32p)&X).U.X = x;
(*(_u32p)&X).L.X = 0;
return *this;
}
F32 operator=( F32 x ){
X = x.X;
return *this;
}
F32 operator=( f32 x ){
x *= 65536.0f;
X = (u32) x;
return *this;
}
operator int(){
return (int) ((s16)(*(_u32p)&X).U.X);
}
operator unsigned int(){
return (*(_u32p)&X).U.X;
}
operator float(){
return ((float)s32(X))/65536.0f;
}
F32 Mul( F32 x ){
u64 T;
T = (u64)X * (u64)x.X;
T >>= 16;
X = (u32) T;
return *this;
}
F32 operator+( int x ){
F32 R;
#ifdef Debug
f32 ev;
ev = f32(s32(X)) / 65536.0f;
ev += x;
#endif
R.X = 0;
(*(_u32p)&R.X).U.X = (u16) x;
R.X += X;
#ifdef Debug
if( s32(ev*10) != s32(f32(s32(R.X))/65536.0f*10.0f) )
printf("%f != %f!\n", ev, f32(s32(R.X))/65536.0f );
#endif
return R;
}
F32 operator+( F32 x ){
F32 R;
#ifdef Debug
f32 ev;
ev = f32(s32(X)) / 65536.0f;
ev += f32(s32(x.X)) / 65536.0f;
#endif
R.X = X + x.X;
#ifdef Debug
if( s32(ev*10) != s32(f32(s32(R.X))/65536.0f*10.0f) )
printf("%f != %f!\n", ev, f32(s32(R.X))/65536.0f );
#endif
return R;
}
F32 operator-( int x ){
F32 R;
#ifdef Debug
f32 ev;
ev = f32(s32(X)) / 65536.0f;
ev -= x;
#endif
R.X = (*(_u32p)&X).U.X-x;
#ifdef Debug
if( s32(ev*10) != s32(f32(s32(R.X))/65536.0f*10.0f) )
printf("%f != %f!\n", ev, f32(s32(R.X))/65536.0f );
#endif
return R;
}
F32 operator-( F32 x ){
F32 R;
R.X = X - x.X;
return *this;
}
F32 operator*( int x ){
F32 R;
#ifdef Debug
f32 ev;
ev = f32(s32(X)) / 65536.0f;
ev *= x;
#endif
R.X = X * x;
#ifdef Debug
if( s32(ev*10) != s32(f32(s32(R.X))/65536.0f*10.0f) )
printf("%f != %f!\n", ev, f32(s32(R.X))/65536.0f );
#endif
return R;
}
F32 operator*( f32 x ){
F32 R;
s64 T;
#ifdef Debug
f32 ev;
ev = f32(s32(X)) / 65536.0f;
ev *= x;
#endif
T = s64(s32(X));
T *= s64(s32(x*65536.0f));
T >>= 16;
R.X = (u32) T;
#ifdef Debug
if( (*(_u64p)&T).U.L.X && !(*(_u64p)&T).U.U.X ) R.X = 0x7FFFFFFF;
if( s32(ev*10) != s32(f32(s32(R.X))/65536.0f*10.0f) )
printf("%f != %f!\n", ev, f32(s32(R.X))/65536.0f );
#endif
return R;
}
F32 operator*( F32 x ){
F32 R;
s64 T;
#ifdef Debug
f32 ev;
ev = f32(s32(X)) / 65536.0f;
ev *= f32(s32(x.X)) / 65536.0f;
#endif
// Something here...
T = s64(s32(X));
T *=s64(s32(x.X));
T >>= 16;
R.X = (u32) T;
#ifdef Debug
if( s32(ev*10) != s32(f32(s32(R.X))/65536.0f*10.0f) )
printf("%f != %f!\n", ev, f32(s32(R.X))/65536.0f );
#endif
return R;
}
F32 operator*=( int x ){
X *= x;
return *this;
}
F32 operator*=( f32 x ){
s64 T;
#ifdef Debug
f32 ev;
ev = f32(s32(X)) / 65536.0f;
ev *= x;
#endif
T = s64(s32(X));
T *= s64(s32(x*65536.0f));
T >>= 16;
X = (u32) T;
#ifdef Debug
if( s32(ev*10) != s32(f32(s32(X))/65536.0f)*10.0f )
printf("%f != %f!\n", ev, f32(s32(X))/65536.0f );
#endif
return *this;
}
F32 operator*=( F32 x ){
s64 T;
#ifdef Debug
f32 ev;
ev = f32(s32(X)) / 65536.0f;
ev *= f32(s32(x.X)) / 65536.0f;
#endif
T = s64(s32(X));
T *= s64(s32(x.X));
T >>= 16;
X = (u32) T;
#ifdef Debug
if( s32(ev*10) != s32(f32(s32(X))/65536.0f)*10.0f )
printf("%f != %f!\n", ev, f32(s32(X))/65536.0f );
#endif
/*
X *= x.X;
X >>= 16;
*/
return *this;
}
F32 operator/( int x ){
F32 R;
R.X = X / x;
return R;
}
F32 operator/( F32 x ){
F32 R;
s64 T;
#ifdef Debug
f32 ev;
ev = f32(s32(X)) / 65536.0f;
ev /= f32(s32(x.X)) / 65536.0f;
#endif
T = 0;
(*(_u64p)&T).U.X = s16((*(_u32p)&X).U.X);
(*(_u32p)&((*(_u64p)&T).L.X)).U.X = (*(_u32p)&X).L.X;
R.X = (u32)( T / s32(x.X) );
#ifdef Debug
if( s32(ev*10) != s32(f32(s32(R.X))/65536.0f*10.0f) )
printf("%f != %f!\n", ev, f32(s32(R.X))/65536.0f );
#endif
// R.X = (X<<16)/x.X;
return R;
}
F32 operator/=( F32 x ){
s64 T;
#ifdef Debug
f32 ev;
ev = f32(s32(X)) / 65536.0f;
ev /= f32(s32(x.X)) / 65536.0f;
#endif
T = 0;
(*(_u64p)&T).U.X = (*(_u32p)&X).U.X;
(*(_u32p)&((*(_u64p)&T).L.X)).U.X = (*(_u32p)&X).L.X;
X = (u32)( T / x.X );
#ifdef Debug
if( s32(ev*10) != s32(f32(s32(X))/65536.0f)*10.0f )
printf("%f != %f!\n", ev, f32(s32(X))/65536.0f );
#endif
return *this;
}
};