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 :
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 :
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"
Use "DGNat" for GLBasic integers, "DGInt" is a double/float.
(DinGsInternal vs DinGsNatural) - very ancient convention.
Having DGInt to describe a float is a bit strange :)
The amended code is thus :
// --------------------------------- //
// 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