* 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:
Cedric BAIL 2009-09-23 16:47:08 +00:00
parent c392f30e71
commit 4ddba5724d
3 changed files with 146 additions and 0 deletions

View File

@ -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);
/**
* @}

View File

@ -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);
}
/**
* @}
*/

View File

@ -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);
}