* eina: Add eina_fptoa.
This is a small piece of code, but a big one for an edje fixed point implementation. SVN revision: 42646
This commit is contained in:
parent
c392f30e71
commit
4ddba5724d
|
@ -56,6 +56,7 @@ EAPI int eina_convert_itoa(int n, char *s) EINA_ARG_NONNULL(2);
|
|||
EAPI int eina_convert_xtoa(unsigned int n, char *s) EINA_ARG_NONNULL(2);
|
||||
EAPI int eina_convert_dtoa(double d, char *des) EINA_ARG_NONNULL(2);
|
||||
EAPI Eina_Bool eina_convert_atod(const char *src, int length, long long *m, long *e) EINA_ARG_NONNULL(1,3,4);
|
||||
EAPI int eina_convert_fptoa(Eina_F32p32 fp, char *des) EINA_ARG_NONNULL(2);
|
||||
|
||||
/**
|
||||
* @}
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
/* undefs EINA_ARG_NONULL() so NULL checks are not compiled out! */
|
||||
#include "eina_safety_checks.h"
|
||||
#include "eina_convert.h"
|
||||
#include "eina_f32p32.h"
|
||||
|
||||
/*============================================================================*
|
||||
* Local *
|
||||
|
@ -71,6 +72,28 @@ static inline void reverse(char s[], int length)
|
|||
}
|
||||
}
|
||||
|
||||
static inline Eina_F32p32 eina_f32p32_mul2(Eina_F32p32 fp)
|
||||
{
|
||||
int64_t low;
|
||||
int64_t high;
|
||||
|
||||
low = (fp & 0x00000000ffffffffLL) << 1;
|
||||
high = (fp >> 32) << 33;
|
||||
|
||||
return low + high;
|
||||
}
|
||||
|
||||
static inline Eina_F32p32 eina_f32p32_mul16(Eina_F32p32 fp)
|
||||
{
|
||||
int64_t low;
|
||||
int64_t high;
|
||||
|
||||
low = (fp & 0x00000000ffffffffLL) << 4;
|
||||
high = (fp >> 32) << 36;
|
||||
|
||||
return low + high;
|
||||
}
|
||||
|
||||
/**
|
||||
* @endcond
|
||||
*/
|
||||
|
@ -569,6 +592,94 @@ eina_convert_dtoa(double d, char *des)
|
|||
return length + eina_convert_itoa(p, des);
|
||||
}
|
||||
|
||||
EAPI int
|
||||
eina_convert_fptoa(Eina_F32p32 fp, char *des)
|
||||
{
|
||||
int length = 0;
|
||||
int p = 0;;
|
||||
int i;
|
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(des, EINA_FALSE);
|
||||
|
||||
if (fp == 0)
|
||||
{
|
||||
memcpy(des, "0x0p+0", 7);
|
||||
return 7;
|
||||
}
|
||||
|
||||
if (fp < 0)
|
||||
{
|
||||
*(des++) = '-';
|
||||
fp = -fp;
|
||||
length++;
|
||||
}
|
||||
|
||||
/* fp >= 1 */
|
||||
if (fp >= 0x0000000100000000LL)
|
||||
{
|
||||
while (fp >= 0x0000000100000000LL)
|
||||
{
|
||||
p++;
|
||||
/* fp /= 2 */
|
||||
fp >>= 1;
|
||||
}
|
||||
}
|
||||
/* fp < 0.5 */
|
||||
else if (fp < 0x80000000)
|
||||
{
|
||||
while (fp < 0x80000000)
|
||||
{
|
||||
p--;
|
||||
/* fp *= 2 */
|
||||
fp <<= 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (p)
|
||||
{
|
||||
p--;
|
||||
/* fp *= 2 */
|
||||
fp <<= 1;
|
||||
}
|
||||
|
||||
*(des++) = '0';
|
||||
*(des++) = 'x';
|
||||
*(des++) = look_up_table[fp >> 32];
|
||||
*(des++) = '.';
|
||||
length += 4;
|
||||
|
||||
for (i = 0; i < 16; i++, length++)
|
||||
{
|
||||
fp &= 0x00000000ffffffffLL;
|
||||
fp <<= 4; /* fp *= 16 */
|
||||
*(des++) = look_up_table[fp >> 32];
|
||||
}
|
||||
|
||||
while (*(des - 1) == '0')
|
||||
{
|
||||
des--;
|
||||
length--;
|
||||
}
|
||||
|
||||
if (*(des - 1) == '.')
|
||||
{
|
||||
des--;
|
||||
length--;
|
||||
}
|
||||
|
||||
*(des++) = 'p';
|
||||
if (p < 0)
|
||||
{
|
||||
*(des++) = '-';
|
||||
p = -p;
|
||||
}
|
||||
else
|
||||
*(des++) = '+';
|
||||
length += 2;
|
||||
|
||||
return length + eina_convert_itoa(p, des);
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
|
|
@ -100,9 +100,43 @@ START_TEST(eina_convert_double)
|
|||
}
|
||||
END_TEST
|
||||
|
||||
static void
|
||||
_eina_convert_fp_check(double d, Eina_F32p32 fp, int length)
|
||||
{
|
||||
char tmp1[128];
|
||||
char tmp2[128];
|
||||
int l1;
|
||||
int l2;
|
||||
|
||||
l1 = eina_convert_dtoa(d, tmp1);
|
||||
l2 = eina_convert_fptoa(fp, tmp2);
|
||||
fail_if(l1 != l2);
|
||||
fail_if(strcmp(tmp1, tmp2) != 0);
|
||||
|
||||
d = -d;
|
||||
fp = -fp;
|
||||
|
||||
l1 = eina_convert_dtoa(d, tmp1);
|
||||
l2 = eina_convert_fptoa(fp, tmp2);
|
||||
fail_if(l1 != l2);
|
||||
fail_if(strcmp(tmp1, tmp2) != 0);
|
||||
}
|
||||
|
||||
START_TEST(eina_convert_fp)
|
||||
{
|
||||
_eina_convert_fp_check(1.0, 0x0000000100000000, 6);
|
||||
_eina_convert_fp_check(0.5, 0x0000000080000000, 8);
|
||||
_eina_convert_fp_check(0.625, 0x00000000a0000000, 8);
|
||||
_eina_convert_fp_check(256.0, 0x0000010000000000, 6);
|
||||
_eina_convert_fp_check(0.5, 0x0000000080000000, 9);
|
||||
_eina_convert_fp_check(128.625, 0x00000080a0000000, 10);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
void
|
||||
eina_test_convert(TCase *tc)
|
||||
{
|
||||
tcase_add_test(tc, eina_convert_simple);
|
||||
tcase_add_test(tc, eina_convert_double);
|
||||
tcase_add_test(tc, eina_convert_fp);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue