167 lines
6.0 KiB
C++
167 lines
6.0 KiB
C++
//========================================================================
|
|
//
|
|
// FixedPoint.h
|
|
//
|
|
// Fixed point type, with C++ operators.
|
|
//
|
|
// Copyright 2004 Glyph & Cog, LLC
|
|
//
|
|
//========================================================================
|
|
|
|
#ifndef FIXEDPOINT_H
|
|
#define FIXEDPOINT_H
|
|
|
|
#include <aconf.h>
|
|
|
|
#if USE_FIXEDPOINT
|
|
|
|
#ifdef USE_GCC_PRAGMAS
|
|
#pragma interface
|
|
#endif
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include "gtypes.h"
|
|
|
|
#define fixptShift 16
|
|
#define fixptMaskL ((1 << fixptShift) - 1)
|
|
#define fixptMaskH (~fixptMaskL)
|
|
|
|
typedef long long FixPtInt64;
|
|
|
|
class FixedPoint {
|
|
public:
|
|
|
|
FixedPoint() { val = 0; }
|
|
FixedPoint(const FixedPoint &x) { val = x.val; }
|
|
FixedPoint(double x) { val = (int)(x * (1 << fixptShift) + 0.5); }
|
|
FixedPoint(int x) { val = x << fixptShift; }
|
|
FixedPoint(long x) { val = x << fixptShift; }
|
|
|
|
operator float()
|
|
{ return (float) val * ((float)1 / (float)(1 << fixptShift)); }
|
|
operator double()
|
|
{ return (double) val * (1.0 / (double)(1 << fixptShift)); }
|
|
operator int()
|
|
{ return val >> fixptShift; }
|
|
|
|
int get16Dot16() { return val; }
|
|
|
|
FixedPoint operator =(FixedPoint x) { val = x.val; return *this; }
|
|
|
|
int operator ==(FixedPoint x) { return val == x.val; }
|
|
int operator ==(double x) { return *this == (FixedPoint)x; }
|
|
int operator ==(int x) { return *this == (FixedPoint)x; }
|
|
int operator ==(long x) { return *this == (FixedPoint)x; }
|
|
|
|
int operator !=(FixedPoint x) { return val != x.val; }
|
|
int operator !=(double x) { return *this != (FixedPoint)x; }
|
|
int operator !=(int x) { return *this != (FixedPoint)x; }
|
|
int operator !=(long x) { return *this != (FixedPoint)x; }
|
|
|
|
int operator <(FixedPoint x) { return val < x.val; }
|
|
int operator <(double x) { return *this < (FixedPoint)x; }
|
|
int operator <(int x) { return *this < (FixedPoint)x; }
|
|
int operator <(long x) { return *this < (FixedPoint)x; }
|
|
|
|
int operator <=(FixedPoint x) { return val <= x.val; }
|
|
int operator <=(double x) { return *this <= (FixedPoint)x; }
|
|
int operator <=(int x) { return *this <= (FixedPoint)x; }
|
|
int operator <=(long x) { return *this <= (FixedPoint)x; }
|
|
|
|
int operator >(FixedPoint x) { return val > x.val; }
|
|
int operator >(double x) { return *this > (FixedPoint)x; }
|
|
int operator >(int x) { return *this > (FixedPoint)x; }
|
|
int operator >(long x) { return *this > (FixedPoint)x; }
|
|
|
|
int operator >=(FixedPoint x) { return val >= x.val; }
|
|
int operator >=(double x) { return *this >= (FixedPoint)x; }
|
|
int operator >=(int x) { return *this >= (FixedPoint)x; }
|
|
int operator >=(long x) { return *this >= (FixedPoint)x; }
|
|
|
|
FixedPoint operator -() { return make(-val); }
|
|
|
|
FixedPoint operator +(FixedPoint x) { return make(val + x.val); }
|
|
FixedPoint operator +(double x) { return *this + (FixedPoint)x; }
|
|
FixedPoint operator +(int x) { return *this + (FixedPoint)x; }
|
|
FixedPoint operator +(long x) { return *this + (FixedPoint)x; }
|
|
|
|
FixedPoint operator +=(FixedPoint x) { val = val + x.val; return *this; }
|
|
FixedPoint operator +=(double x) { return *this += (FixedPoint)x; }
|
|
FixedPoint operator +=(int x) { return *this += (FixedPoint)x; }
|
|
FixedPoint operator +=(long x) { return *this += (FixedPoint)x; }
|
|
|
|
FixedPoint operator -(FixedPoint x) { return make(val - x.val); }
|
|
FixedPoint operator -(double x) { return *this - (FixedPoint)x; }
|
|
FixedPoint operator -(int x) { return *this - (FixedPoint)x; }
|
|
FixedPoint operator -(long x) { return *this - (FixedPoint)x; }
|
|
|
|
FixedPoint operator -=(FixedPoint x) { val = val - x.val; return *this; }
|
|
FixedPoint operator -=(double x) { return *this -= (FixedPoint)x; }
|
|
FixedPoint operator -=(int x) { return *this -= (FixedPoint)x; }
|
|
FixedPoint operator -=(long x) { return *this -= (FixedPoint)x; }
|
|
|
|
FixedPoint operator *(FixedPoint x) { return make(mul(val, x.val)); }
|
|
FixedPoint operator *(double x) { return *this * (FixedPoint)x; }
|
|
FixedPoint operator *(int x) { return *this * (FixedPoint)x; }
|
|
FixedPoint operator *(long x) { return *this * (FixedPoint)x; }
|
|
|
|
FixedPoint operator *=(FixedPoint x) { val = mul(val, x.val); return *this; }
|
|
FixedPoint operator *=(double x) { return *this *= (FixedPoint)x; }
|
|
FixedPoint operator *=(int x) { return *this *= (FixedPoint)x; }
|
|
FixedPoint operator *=(long x) { return *this *= (FixedPoint)x; }
|
|
|
|
FixedPoint operator /(FixedPoint x) { return make(div(val, x.val)); }
|
|
FixedPoint operator /(double x) { return *this / (FixedPoint)x; }
|
|
FixedPoint operator /(int x) { return *this / (FixedPoint)x; }
|
|
FixedPoint operator /(long x) { return *this / (FixedPoint)x; }
|
|
|
|
FixedPoint operator /=(FixedPoint x) { val = div(val, x.val); return *this; }
|
|
FixedPoint operator /=(double x) { return *this /= (FixedPoint)x; }
|
|
FixedPoint operator /=(int x) { return *this /= (FixedPoint)x; }
|
|
FixedPoint operator /=(long x) { return *this /= (FixedPoint)x; }
|
|
|
|
static FixedPoint abs(FixedPoint x) { return make(::abs(x.val)); }
|
|
|
|
static int floor(FixedPoint x) { return x.val >> fixptShift; }
|
|
|
|
static int ceil(FixedPoint x)
|
|
{ return (x.val & fixptMaskL) ? ((x.val >> fixptShift) + 1)
|
|
: (x.val >> fixptShift); }
|
|
|
|
static int round(FixedPoint x)
|
|
{ return (x.val + (1 << (fixptShift - 1))) >> fixptShift; }
|
|
|
|
// Computes (x+y)/2 avoiding overflow and LSbit accuracy issues.
|
|
static FixedPoint avg(FixedPoint x, FixedPoint y)
|
|
{ return make((x.val >> 1) + (y.val >> 1) + ((x.val | y.val) & 1)); }
|
|
|
|
|
|
static FixedPoint sqrt(FixedPoint x);
|
|
|
|
static FixedPoint pow(FixedPoint x, FixedPoint y);
|
|
|
|
// Compute *result = x/y; return false if there is an underflow or
|
|
// overflow.
|
|
static GBool divCheck(FixedPoint x, FixedPoint y, FixedPoint *result);
|
|
|
|
// Compute abs(m11*m22 - m12*m21) >= epsilon, handling the case
|
|
// where the multiplications overflow.
|
|
static GBool checkDet(FixedPoint m11, FixedPoint m12,
|
|
FixedPoint m21, FixedPoint m22,
|
|
FixedPoint epsilon);
|
|
|
|
private:
|
|
|
|
static FixedPoint make(int valA) { FixedPoint x; x.val = valA; return x; }
|
|
|
|
static int mul(int x, int y);
|
|
static int div(int x, int y);
|
|
|
|
int val; // fixed point: (n-fixptShift).(fixptShift)
|
|
};
|
|
|
|
#endif // USE_FIXEDPOINT
|
|
|
|
#endif
|