forked from enlightenment/efl
* eina: Improve precision of f32p32 sinus/cosinus.
SVN revision: 44322
This commit is contained in:
parent
04a156cda0
commit
63d651b7ad
|
@ -20,6 +20,8 @@
|
|||
#ifndef EINA_FP_H_
|
||||
# define EINA_FP_H_
|
||||
|
||||
#include "eina_types.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
typedef unsigned __int64 uint64_t;
|
||||
typedef signed __int64 int64_t;
|
||||
|
@ -47,6 +49,9 @@ static inline Eina_F32p32 eina_f32p32_div(Eina_F32p32 a, Eina_F32p32 b);
|
|||
static inline Eina_F32p32 eina_f32p32_sqrt(Eina_F32p32 a);
|
||||
static inline unsigned int eina_f32p32_fracc_get(Eina_F32p32 v);
|
||||
|
||||
// dont use llabs - issues if not on 64bit
|
||||
#define eina_fp32p32_llabs(a) ((a < 0) ? -(a) : (a))
|
||||
|
||||
EAPI Eina_F32p32 eina_f32p32_cos(Eina_F32p32 a);
|
||||
EAPI Eina_F32p32 eina_f32p32_sin(Eina_F32p32 a);
|
||||
|
||||
|
|
|
@ -21,9 +21,6 @@
|
|||
|
||||
#include <stdlib.h>
|
||||
|
||||
// dont use llabs - issues if not on 64bit
|
||||
#define _eina_fp32p32_llabs(a) ((a < 0) ? -(a) : (a))
|
||||
|
||||
static inline Eina_F32p32
|
||||
eina_f32p32_add(Eina_F32p32 a, Eina_F32p32 b)
|
||||
{
|
||||
|
@ -48,8 +45,8 @@ eina_f32p32_mul(Eina_F32p32 a, Eina_F32p32 b)
|
|||
Eina_F32p32 sign;
|
||||
|
||||
sign = a ^ b;
|
||||
as = _eina_fp32p32_llabs(a);
|
||||
bs = _eina_fp32p32_llabs(b);
|
||||
as = eina_fp32p32_llabs(a);
|
||||
bs = eina_fp32p32_llabs(b);
|
||||
|
||||
up = (as >> 16) * (bs >> 16);
|
||||
down = (as & 0xFFFF) * (bs & 0xFFFF);
|
||||
|
@ -76,7 +73,7 @@ eina_f32p32_div(Eina_F32p32 a, Eina_F32p32 b)
|
|||
if (b == 0)
|
||||
return sign < 0 ? (Eina_F32p32) 0x8000000000000000ll : (Eina_F32p32) 0x7FFFFFFFFFFFFFFFll;
|
||||
|
||||
result = (eina_f32p32_mul(_eina_fp32p32_llabs(a), (((uint64_t) 1 << 62) / ((uint64_t)(_eina_fp32p32_llabs(b)) >> 2))));
|
||||
result = (eina_f32p32_mul(eina_fp32p32_llabs(a), (((uint64_t) 1 << 62) / ((uint64_t)(eina_fp32p32_llabs(b)) >> 2))));
|
||||
|
||||
return sign < 0 ? - result : result;
|
||||
}
|
||||
|
|
|
@ -124,27 +124,38 @@ eina_f32p32_cos(Eina_F32p32 a)
|
|||
Eina_F32p32 F32P32_3PI2;
|
||||
Eina_F32p32 remainder_2PI;
|
||||
Eina_F32p32 remainder_PI;
|
||||
Eina_F32p32 interpol;
|
||||
Eina_F32p32 result;
|
||||
int index;
|
||||
int index2;
|
||||
|
||||
F32P32_2PI = EINA_F32P32_PI << 1;
|
||||
F32P32_PI2 = EINA_F32P32_PI >> 1;
|
||||
F32P32_3PI2 = EINA_F32P32_PI + F32P32_PI2;
|
||||
|
||||
/* Take advantage of cosinus symetrie. */
|
||||
a = eina_fp32p32_llabs(a);
|
||||
|
||||
/* Find table entry in 0 to PI / 2 */
|
||||
remainder_PI = a - (a / EINA_F32P32_PI) * EINA_F32P32_PI;
|
||||
|
||||
/* Find which case from 0 to 2 * PI */
|
||||
remainder_2PI = a - (a / F32P32_2PI) * F32P32_2PI;
|
||||
|
||||
index = eina_f32p32_int_to(eina_f32p32_div(eina_f32p32_scale(remainder_PI, MAX_PREC * 2),
|
||||
EINA_F32P32_PI));
|
||||
|
||||
|
||||
interpol = eina_f32p32_div(eina_f32p32_scale(remainder_PI, MAX_PREC * 2),
|
||||
EINA_F32P32_PI);
|
||||
index = eina_f32p32_int_to(interpol);
|
||||
if (index >= MAX_PREC)
|
||||
index = 2 * MAX_PREC - (index - 1);
|
||||
|
||||
result = eina_trigo[index];
|
||||
index2 = index + 1;
|
||||
if (index2 == MAX_PREC)
|
||||
index2 = index - 1;
|
||||
|
||||
result = eina_f32p32_add(eina_trigo[index],
|
||||
eina_f32p32_mul(eina_f32p32_sub(eina_trigo[index],
|
||||
eina_trigo[index2]),
|
||||
(Eina_F32p32) eina_f32p32_fracc_get(interpol)));
|
||||
|
||||
if (0 <= remainder_2PI && remainder_2PI < F32P32_PI2)
|
||||
return result;
|
||||
|
@ -164,8 +175,10 @@ eina_f32p32_sin(Eina_F32p32 a)
|
|||
Eina_F32p32 F32P32_3PI2;
|
||||
Eina_F32p32 remainder_2PI;
|
||||
Eina_F32p32 remainder_PI;
|
||||
Eina_F32p32 interpol;
|
||||
Eina_F32p32 result;
|
||||
int index;
|
||||
int index2;
|
||||
|
||||
F32P32_2PI = EINA_F32P32_PI << 1;
|
||||
F32P32_PI2 = EINA_F32P32_PI >> 1;
|
||||
|
@ -174,18 +187,29 @@ eina_f32p32_sin(Eina_F32p32 a)
|
|||
/* We only have a table for cosinus, but sin(a) = cos(pi / 2 - a) */
|
||||
a = eina_f32p32_sub(F32P32_PI2, a);
|
||||
|
||||
/* Take advantage of cosinus symetrie. */
|
||||
a = eina_fp32p32_llabs(a);
|
||||
|
||||
/* Find table entry in 0 to PI / 2 */
|
||||
remainder_PI = a - (a / EINA_F32P32_PI) * EINA_F32P32_PI;
|
||||
|
||||
/* Find which case from 0 to 2 * PI */
|
||||
remainder_2PI = a - (a / F32P32_2PI) * F32P32_2PI;
|
||||
|
||||
index = eina_f32p32_int_to(eina_f32p32_div(eina_f32p32_scale(remainder_PI, MAX_PREC * 2),
|
||||
EINA_F32P32_PI));
|
||||
interpol = eina_f32p32_div(eina_f32p32_scale(remainder_PI, MAX_PREC * 2),
|
||||
EINA_F32P32_PI);
|
||||
index = eina_f32p32_int_to(interpol);
|
||||
if (index >= MAX_PREC)
|
||||
index = MAX_PREC - (index + 1);
|
||||
|
||||
result = eina_trigo[index];
|
||||
index2 = index + 1;
|
||||
if (index2 == MAX_PREC)
|
||||
index2 = index - 1;
|
||||
|
||||
result = eina_f32p32_add(eina_trigo[index],
|
||||
eina_f32p32_mul(eina_f32p32_sub(eina_trigo[index],
|
||||
eina_trigo[index2]),
|
||||
(Eina_F32p32) eina_f32p32_fracc_get(interpol)));
|
||||
|
||||
if (0 <= remainder_2PI && remainder_2PI < F32P32_PI2)
|
||||
return result;
|
||||
|
|
Loading…
Reference in New Issue