Fixed Point API

## Fixed Point API Fixed Point API — Fixed Point API |

## Synopsis

    typedef             CoglFixed;
    #define             COGL_FIXED_BITS
    #define             COGL_FIXED_Q
    #define             COGL_FIXED_MAX
    #define             COGL_FIXED_MIN

    #define             COGL_FIXED_FROM_FLOAT               (x)
    #define             COGL_FIXED_TO_FLOAT                 (x)
    #define             COGL_FIXED_FROM_INT                 (x)
    #define             COGL_FIXED_TO_INT                   (x)
    #define             COGL_FIXED_FROM_DOUBLE              (x)
    #define             COGL_FIXED_TO_DOUBLE                (x)
    #define             COGL_FLOAT_TO_INT                   (x)
    #define             COGL_FLOAT_TO_UINT                  (x)

    #define             COGL_FIXED_EPSILON
    #define             COGL_FIXED_1
    #define             COGL_FIXED_0_5
    #define             COGL_FIXED_30
    #define             COGL_FIXED_45
    #define             COGL_FIXED_60
    #define             COGL_FIXED_90
    #define             COGL_FIXED_120
    #define             COGL_FIXED_180
    #define             COGL_FIXED_240
    #define             COGL_FIXED_255
    #define             COGL_FIXED_270
    #define             COGL_FIXED_360

    #define             COGL_FIXED_MUL                      (a,
                                                             b)
    #define             COGL_FIXED_DIV                      (a,
                                                             b)
    #define             COGL_FIXED_MUL_DIV                  (a,
                                                             b,
                                                             c)
    #define             COGL_FIXED_FAST_DIV                 (a,
                                                             b)
    #define             COGL_FIXED_FAST_MUL                 (a,
                                                             b)
    #define             COGL_FIXED_FRACTION                 (x)
    #define             COGL_FIXED_FLOOR                    (x)
    #define             COGL_FIXED_CEIL                     (x)

    #define             COGL_FIXED_2_PI
    #define             COGL_FIXED_PI
    #define             COGL_FIXED_PI_2
    #define             COGL_FIXED_PI_4
    #define             COGL_RADIANS_TO_DEGREES

    #define             COGL_SQRTI_ARG_10_PERCENT
    #define             COGL_SQRTI_ARG_5_PERCENT
    #define             COGL_SQRTI_ARG_MAX
    int                 cogl_sqrti                          (int x);

    CoglFixed           cogl_fixed_atan2                    (CoglFixed a,
                                                             CoglFixed b);
    CoglFixed           cogl_fixed_atan                     (CoglFixed a);
    CoglFixed           cogl_fixed_cos                      (CoglFixed angle);
    CoglFixed           cogl_fixed_log2                     (unsigned int x);
    unsigned int        cogl_fixed_pow                      (unsigned int x,
                                                             CoglFixed y);
    unsigned int        cogl_fixed_pow2                     (CoglFixed x);
    CoglFixed           cogl_fixed_sin                      (CoglFixed angle);
    CoglFixed           cogl_fixed_sqrt                     (CoglFixed x);
    CoglFixed           cogl_fixed_tan                      (CoglFixed angle);
    CoglFixed           cogl_fixed_div                      (CoglFixed a,
                                                             CoglFixed b);
    CoglFixed           cogl_fixed_mul                      (CoglFixed a,
                                                             CoglFixed b);
    CoglFixed           cogl_fixed_mul_div                  (CoglFixed a,
                                                             CoglFixed b,
                                                             CoglFixed c);

    typedef             CoglAngle;
    #define             COGL_ANGLE_FROM_DEG                 (x)
    #define             COGL_ANGLE_FROM_DEGX                (x)
    #define             COGL_ANGLE_TO_DEG                   (x)
    #define             COGL_ANGLE_TO_DEGX                  (x)
    CoglFixed           cogl_angle_cos                      (CoglAngle angle);
    CoglFixed           cogl_angle_sin                      (CoglAngle angle);
    CoglFixed           cogl_angle_tan                      (CoglAngle angle);

## Description

COGL has a fixed point API targeted at platforms without a floating point unit, such as embedded devices. On such platforms this API should be preferred to the floating point one as it does not trigger the slow path of software emulation, relying on integer math for fixed-to-floating and floating-to-fixed notations conversion.

It is not recommened for use on platforms with a floating point unit (e.g. desktop systems), nor for use in language bindings.

Basic rules of Fixed Point arithmethic:

- Two fixed point numbers can be directly added, subtracted and have their modulus taken.

- To add other numerical type to a fixed point number it has to be first converted to fixed point.

- A fixed point number can be directly multiplied or divided by an integer.

- Two fixed point numbers can only be multiplied and divided by the provided `COGL_FIXED_MUL` and `COGL_FIXED_DIV` macros.

The fixed point API is available since COGL 1.0.

## Details

### CoglFixed

    typedef gint32 CoglFixed;

Fixed point number using a (16.16) notation.

### COGL_FIXED_BITS

    #define COGL_FIXED_BITS         (32)

Evaluates to the number of bits used by the CoglFixed type.

Since 1.0

### COGL_FIXED_Q

    #define COGL_FIXED_Q            (COGL_FIXED_BITS - 16)

Evaluates to the number of bits used for the non-integer part of the CoglFixed type.

Since 1.0

### COGL_FIXED_MAX

    #define COGL_FIXED_MAX          (0x7fffffff)

The biggest number representable using CoglFixed

Since 1.0

### COGL_FIXED_MIN

    #define COGL_FIXED_MIN          (0x80000000)

The smallest number representable using CoglFixed

Since 1.0

### COGL_FIXED_FROM_FLOAT()

    #define COGL_FIXED_FROM_FLOAT(x)        ((float) cogl_double_to_fixed (x))

Converts `x` from a floating point to a fixed point notation.

`x` : | a floating point number

Since 1.0

### COGL_FIXED_TO_FLOAT()

    #define COGL_FIXED_TO_FLOAT(x)          ((float) ((int)(x) / 65536.0))

Converts `x` from a fixed point to a floating point notation, in single precision.

`x` : | a CoglFixed number

Since 1.0

### COGL_FIXED_FROM_INT()

    #define COGL_FIXED_FROM_INT(x)          ((x) << COGL_FIXED_Q)

Converts `x` from an integer to a fixed point notation.

`x` : | an integer number

Since 1.0

### COGL_FIXED_TO_INT()

    #define COGL_FIXED_TO_INT(x)            ((x) >> COGL_FIXED_Q)

Converts `x` from a fixed point notation to an integer, dropping the fractional part without rounding.

`x` : | a CoglFixed number

Since 1.0

### COGL_FIXED_FROM_DOUBLE()

    #define COGL_FIXED_FROM_DOUBLE(x)       (cogl_double_to_fixed (x))

Converts `x` from a double precision, floating point to a fixed point notation.

`x` : | a floating point number

Since 1.0

### COGL_FIXED_TO_DOUBLE()

    #define COGL_FIXED_TO_DOUBLE(x)         ((double) ((int)(x) / 65536.0))

Converts `x` from a fixed point to a floating point notation, in double precision.

`x` : | a CoglFixed number

Since 1.0

### COGL_FLOAT_TO_INT()

    #define COGL_FLOAT_TO_INT(x)            (cogl_double_to_int ((x)))

Converts `x` from a floating point notation to a signed integer.

`x` : | a floatint point number

Since 1.0

### COGL_FLOAT_TO_UINT()

    #define COGL_FLOAT_TO_UINT(x)           (cogl_double_to_uint ((x)))

Converts `x` from a floating point notation to an unsigned integer.

`x` : | a floatint point number

Since 1.0

### COGL_FIXED_EPSILON

    #define COGL_FIXED_EPSILON      (1)

A very small number expressed as a CoglFixed number.

Since 1.0

### COGL_FIXED_1

    #define COGL_FIXED_1            (1 << COGL_FIXED_Q)

The number 1 expressed as a CoglFixed number.

Since 1.0

### COGL_FIXED_0_5

    #define COGL_FIXED_0_5          (32768)

The number 0.5 expressed as a CoglFixed number.

Since 1.0

### COGL_FIXED_30

    #define COGL_FIXED_30           (COGL_FIXED_FROM_INT (30))

Evaluates to the number 30 in fixed point notation.

Since 1.0

### COGL_FIXED_45

    #define COGL_FIXED_45           (COGL_FIXED_FROM_INT (45))

Evaluates to the number 45 in fixed point notation.

Since 1.0

### COGL_FIXED_60

    #define COGL_FIXED_60           (COGL_FIXED_FROM_INT (60))

Evaluates to the number 60 in fixed point notation.

Since 1.0

### COGL_FIXED_90

    #define COGL_FIXED_90           (COGL_FIXED_FROM_INT (90))

Evaluates to the number 90 in fixed point notation.

Since 1.0

### COGL_FIXED_120

    #define COGL_FIXED_120          (COGL_FIXED_FROM_INT (120))

Evaluates to the number 120 in fixed point notation.

Since 1.0

### COGL_FIXED_180

    #define COGL_FIXED_180          (COGL_FIXED_FROM_INT (180))

Evaluates to the number 180 in fixed point notation.

Since 1.0

### COGL_FIXED_240

    #define COGL_FIXED_240          (COGL_FIXED_FROM_INT (240))

Evaluates to the number 240 in fixed point notation.

Since 1.0

### COGL_FIXED_255

    #define COGL_FIXED_255          (COGL_FIXED_FROM_INT (255))

Evaluates to the number 255 in fixed point notation.

Since 1.0

### COGL_FIXED_270

    #define COGL_FIXED_270          (COGL_FIXED_FROM_INT (270))

Evaluates to the number 270 in fixed point notation.

Since 1.0

### COGL_FIXED_360

    #define COGL_FIXED_360          (COGL_FIXED_FROM_INT (360))

Evaluates to the number 360 in fixed point notation.

Since 1.0

### COGL_FIXED_MUL()

    #define COGL_FIXED_MUL(a,b)             (cogl_fixed_mul ((a), (b)))

Computes (a * b).

`a` : | a CoglFixed number
`b` : | a CoglFixed number

Since 1.0

### COGL_FIXED_DIV()

    #define COGL_FIXED_DIV(a,b)             (cogl_fixed_div ((a), (b)))

Computes (a / b).

`a` : | a CoglFixed number
`b` : | a CoglFixed number

Since 1.0

### COGL_FIXED_MUL_DIV()

    #define COGL_FIXED_MUL_DIV(a,b,c)       (cogl_fixed_mul_div ((a), (b), (c)))

Computes ((a * b) / c). It is logically equivalent to:

    1
    res = COGL_FIXED_DIV (COGL_FIXED_MUL (a, b), c);

But it is shorter to type.

`a` : | a CoglFixed number
`b` : | a CoglFixed number
`c` : | a CoglFixed number

Since 1.0

### COGL_FIXED_FAST_DIV()

    #define COGL_FIXED_FAST_DIV(a,b)        ((((a) << 8) / (b)) << 8)

Fast version of `COGL_FIXED_DIV`, implemented as a macro.

### Note

This macro might lose precision. If the precision of the result is important use `COGL_FIXED_DIV` instead.

`a` : | a CoglFixed number
`b` : | a CoglFixed number

Since 1.0

### COGL_FIXED_FAST_MUL()

    #define COGL_FIXED_FAST_MUL(a,b)        ((a) >> 8) * ((b) >> 8)

Fast version of `COGL_FIXED_MUL`, implemented as a macro.

### Note

This macro might lose precision. If the precision of the result is important use `COGL_FIXED_MUL` instead.

`a` : | a CoglFixed number
`b` : | a CoglFixed number

Since 1.0

### COGL_FIXED_FRACTION()

    #define COGL_FIXED_FRACTION(x)          ((x) & ((1 << COGL_FIXED_Q) - 1))

Retrieves the fractionary part of `x`.

`x` : | a CoglFixed number

Since 1.0

### COGL_FIXED_FLOOR()

    #define             COGL_FIXED_FLOOR(x)

Rounds down a fixed point number to the previous integer.

`x` : | a CoglFixed number

Since 1.0

### COGL_FIXED_CEIL()

    #define COGL_FIXED_CEIL(x)              (COGL_FIXED_FLOOR ((x) + 0xffff))

Rounds up a fixed point number to the next integer.

`x` : | a CoglFixed number

Since 1.0

### COGL_FIXED_2_PI

    #define COGL_FIXED_2_PI         (0x0006487f)

Two times pi, expressed as a CoglFixed number.

Since 1.0

### COGL_FIXED_PI

    #define COGL_FIXED_PI           (0x0003243f)

The number pi, expressed as a CoglFixed number.

Since 1.0

### COGL_FIXED_PI_2

    #define COGL_FIXED_PI_2         (0x00019220)

Half pi, expressed as a CoglFixed number.

Since 1.0

### COGL_FIXED_PI_4

    #define COGL_FIXED_PI_4         (0x0000c910)

pi / 4, expressed as CoglFixed number.

Since 1.0

### COGL_RADIANS_TO_DEGREES

    #define COGL_RADIANS_TO_DEGREES (0x394bb8)

Evaluates to 180 / pi in fixed point notation.

Since 1.0

### COGL_SQRTI_ARG_10_PERCENT

    #define COGL_SQRTI_ARG_10_PERCENT 5590

Maximum argument that can be passed to `cogl_sqrti()` for which the resulting error is < 10%

Since 1.0

### COGL_SQRTI_ARG_5_PERCENT

    #define COGL_SQRTI_ARG_5_PERCENT 210

Maximum argument that can be passed to `cogl_sqrti()` for which the resulting error is < 5%

Since 1.0

### COGL_SQRTI_ARG_MAX

    #define COGL_SQRTI_ARG_MAX 0x3fffff

Maximum argument that can be passed to `cogl_sqrti()` function.

Since 1.0

### cogl_sqrti ()

    int                 cogl_sqrti                          (int x);

Very fast fixed point implementation of square root for integers.

This function is at least 6x faster than clib `sqrt()` on x86, and (this is not a typo!) about 500x faster on ARM without FPU. It's error is < 5% for arguments < `COGL_SQRTI_ARG_5_PERCENT` and < 10% for arguments < `COGL_SQRTI_ARG_10_PERCENT`. The maximum argument that can be passed to this function is COGL_SQRTI_ARG_MAX.

`x` : | integer value
Returns : | integer square root.

Since 0.2

### cogl_fixed_atan2 ()

    CoglFixed           cogl_fixed_atan2                    (CoglFixed a,
                                                             CoglFixed b);

Computes the arc tangent of `a` / `b` but uses the sign of both arguments to return the angle in right quadrant.

`a` : | the numerator as a CoglFixed number
`b` : | the denominator as a CoglFixed number
Returns : | the arc tangent of the passed fraction, in fixed point notation

Since 1.0

### cogl_fixed_atan ()

    CoglFixed           cogl_fixed_atan                     (CoglFixed a);

Computes the arc tangent of `a`.

`a` : | a CoglFixed number
Returns : | the arc tangent of the passed value, in fixed point notation

Since 1.0

### cogl_fixed_cos ()

    CoglFixed           cogl_fixed_cos                      (CoglFixed angle);

Computes the cosine of `angle`.

`angle` : | a CoglFixed number
Returns : | the cosine of the passed angle, in fixed point notation

Since 1.0

### cogl_fixed_log2 ()

    CoglFixed           cogl_fixed_log2                     (unsigned int x);

Calculates base 2 logarithm.

This function is some 2.5 times faster on x86, and over 12 times faster on fpu-less arm, than using libc `log()`.

`x` : | value to calculate base 2 logarithm from
Returns : | base 2 logarithm.

Since 1.0

### cogl_fixed_pow ()

    unsigned int        cogl_fixed_pow                      (unsigned int x,
                                                             CoglFixed y);

Calculates `x` to the `y` power.

`x` : | base
`y` : | CoglFixed exponent
Returns : | the power of `x` to the `y`

Since 1.0

### cogl_fixed_pow2 ()

    unsigned int        cogl_fixed_pow2                     (CoglFixed x);

Calculates 2 to the `x` power.

This function is around 11 times faster on x86, and around 22 times faster on fpu-less arm than libc pow(2, x).

`x` : | a CoglFixed number
Returns : | the power of 2 to the passed value

Since 1.0

### cogl_fixed_sin ()

    CoglFixed           cogl_fixed_sin                      (CoglFixed angle);

Computes the sine of `angle`.

`angle` : | a CoglFixed number
Returns : | the sine of the passed angle, in fixed point notation

Since 1.0

### cogl_fixed_sqrt ()

    CoglFixed           cogl_fixed_sqrt                     (CoglFixed x);

Computes the square root of `x`.

`x` : | a CoglFixed number
Returns : | the square root of the passed value, in floating point notation

Since 1.0

### cogl_fixed_tan ()

    CoglFixed           cogl_fixed_tan                      (CoglFixed angle);

Computes the tangent of `angle`.

`angle` : | a CoglFixed number
Returns : | the tangent of the passed angle, in fixed point notation

Since 1.0

### cogl_fixed_div ()

    CoglFixed           cogl_fixed_div                      (CoglFixed a,
                                                             CoglFixed b);

### cogl_fixed_mul ()

    CoglFixed           cogl_fixed_mul                      (CoglFixed a,
                                                             CoglFixed b);

### cogl_fixed_mul_div ()

    CoglFixed           cogl_fixed_mul_div                  (CoglFixed a,
                                                             CoglFixed b,
                                                             CoglFixed c);

### CoglAngle

    typedef gint32 CoglAngle;

Integer representation of an angle such that 1024 corresponds to full circle (i.e., 2 * pi).

Since 1.0

### COGL_ANGLE_FROM_DEG()

    #define COGL_ANGLE_FROM_DEG(x)  (COGL_FLOAT_TO_INT (((float)(x) * 1024.0f) / 360.0f))

Converts an angle in degrees into a CoglAngle.

`x` : | an angle in degrees in floating point notation

Since 1.0

### COGL_ANGLE_FROM_DEGX()

    #define COGL_ANGLE_FROM_DEGX(x) (COGL_FIXED_TO_INT ((((x) / 360) * 1024) + COGL_FIXED_0_5))

Converts an angle in degrees into a CoglAngle.

`x` : | an angle in degrees in fixed point notation

Since 1.0

### COGL_ANGLE_TO_DEG()

    #define COGL_ANGLE_TO_DEG(x)    (((float)(x) * 360.0) / 1024.0)

Converts a CoglAngle into an angle in degrees, using floatint point notation.

`x` : | a CoglAngle

Since 1.0

### COGL_ANGLE_TO_DEGX()

    #define COGL_ANGLE_TO_DEGX(x)   (COGL_FIXED_FROM_INT ((x) * 45) / 128)

Converts a CoglAngle into an angle in degrees, using fixed point notation

`x` : | a CoglAngle

Since 1.0

### cogl_angle_cos ()

    CoglFixed           cogl_angle_cos                      (CoglAngle angle);

Computes the cosine of `angle`

`angle` : | an angle expressed using CoglAngle
Returns : | the cosine of the passed angle

Since 1.0

### cogl_angle_sin ()

    CoglFixed           cogl_angle_sin                      (CoglAngle angle);

Computes the sine of `angle`

`angle` : | an angle expressed using CoglAngle
Returns : | the sine of the passed angle

Since 1.0

### cogl_angle_tan ()

    CoglFixed           cogl_angle_tan                      (CoglAngle angle);

Computes the tangent of `angle`

`angle` : | an angle expressed using CoglAngle
Returns : | the tangent of the passed angle

Since 1.0