Fixed-point routines

Previous topic - Next topic

MrTAToad

I've written a set of fixed-point routines, which interface with a C++ class written by Tixy (http://home.clara.net/tixy/source/index.html#Fixed-Point%20Maths)

In order to get this to compile, you will need to download (in the same location as the project that you will be using the routine), the common header, fix.h and fix.hpp

Then, you can use the following interface functions :

Code (glbasic) Select
FUNCTION dummy:
ENDFUNCTION

INLINE
}

#include "fix.c"
Fix calc;

namespace __GLBASIC__{
ENDINLINE

// Conversion routines
FUNCTION itofix%:value%
INLINE
return (DGInt) ((int) value<<16);
ENDINLINE
ENDFUNCTION

FUNCTION fixtoi%:value%,which%=TRUE
INLINE
if (which)
{
return (DGInt) ((int) ((value>>15)+1)>>1);
}
else
{
return (DGInt) ((int) (value>>16));
}
ENDINLINE
ENDFUNCTION

FUNCTION ftofix%:value
INLINE
fix result;

result=(double) value*65535.01;
return (DGInt) result;
ENDINLINE
ENDFUNCTION

FUNCTION fixadd%:a%,b%
INLINE
return (DGInt) calc.Add(a,b);
ENDINLINE
ENDFUNCTION

FUNCTION fixsub%:a%,b%
INLINE
return (DGInt) calc.Sub(a,b);
ENDINLINE
ENDFUNCTION

FUNCTION fixmult%:a%,b%
INLINE
return (DGInt) calc.Mul(a,b);
ENDINLINE
ENDFUNCTION

FUNCTION fixdiv%:a%,b%
INLINE
return (DGInt) calc.Div(a,b);
ENDINLINE
ENDFUNCTION

FUNCTION fixtof:value%,which%=TRUE
INLINE
DGInt intPart;
DGInt decPart;
double result;

intPart=fixtoi(value,which);
decPart=value & 65535;
result=(double) intPart+((double) decPart/65535.01);

return result;
ENDINLINE
ENDFUNCTION


The test code is :

Code (glbasic) Select
LOCAL a%,b%,r%

a%=ftofix(1.0)
b%=ftofix(10.0)
r%=fixsub(a%,b%)
DEBUG "Result (Fixed) : "+r%+"\n"
DEBUG "Result (Float) : "+fixtof(r%)+"\n"


Kitty Hello

Use "DGNat" for GLBasic integers, "DGInt" is a double/float.
(DinGsInternal vs DinGsNatural) - very ancient convention.

MrTAToad

#2
Having DGInt to describe a float is a bit strange :)

The amended code is thus :

Code (glbasic) Select
// --------------------------------- //
// Project: Fixed point
// Start: Friday, January 16, 2009
// IDE Version: 6.136

FUNCTION dummy:
ENDFUNCTION

INLINE
}

#include "fix.c"
Fix calc;

namespace __GLBASIC__{
ENDINLINE

// Conversion routines
FUNCTION itofix%:value%
INLINE
return (DGNat) ((int) value<<16);
ENDINLINE
ENDFUNCTION

FUNCTION fixtoi%:value%,which%=TRUE
INLINE
if (which)
{
return (DGNat) ((int) ((value>>15)+1)>>1);
}
else
{
return (DGNat) ((int) (value>>16));
}
ENDINLINE
ENDFUNCTION

FUNCTION ftofix%:value
INLINE
fix result;

result=(fix) ((double) value*65535.01);
return (DGNat) result;
ENDINLINE
ENDFUNCTION

FUNCTION fixadd%:a%,b%
INLINE
return (DGNat) calc.Add(a,b);
ENDINLINE
ENDFUNCTION

FUNCTION fixsub%:a%,b%
INLINE
return (DGNat) calc.Sub(a,b);
ENDINLINE
ENDFUNCTION

FUNCTION fixmult%:a%,b%
INLINE
return (DGNat) calc.Mul(a,b);
ENDINLINE
ENDFUNCTION

FUNCTION fixdiv%:a%,b%
INLINE
return (DGNat) calc.Div(a,b);
ENDINLINE
ENDFUNCTION

FUNCTION fixtof:value%,which%=TRUE
INLINE
DGNat intPart;
DGNat decPart;
DGInt result; // Actually a float

intPart=fixtoi(value,which);
decPart=value & 65535;
result=(DGInt) intPart+((double) decPart/65535.01);

return result;
ENDINLINE
ENDFUNCTION