Author Topic: Fixed-point routines  (Read 3896 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"
 

Offline Kitty Hello

  • code monkey
  • Administrator
  • Prof. Inline
  • *******
  • Posts: 10723
  • here on my island the sea says 'hello'
    • View Profile
    • http://www.glbasic.com
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 »