### Author Topic: Fixed-point routines  (Read 3755 times)

#### MrTAToad

• Guest
##### Fixed-point routines
« on: 2009-Jan-17 »
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

• code monkey
• Administrator
• Prof. Inline
• Posts: 10695
• here on my island the sea says 'hello'
##### Re: Fixed-point routines
« Reply #1 on: 2009-Jan-20 »
Use "DGNat" for GLBasic integers, "DGInt" is a double/float.
(DinGsInternal vs DinGsNatural) - very ancient convention.

#### MrTAToad

• Guest
##### Re: Fixed-point routines
« Reply #2 on: 2009-Jan-20 »
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

« Last Edit: 2009-Jan-20 by MrTAToad »