This is a small piece of code, but a big one for an edje fixed point implementation.
SVN revision: 42646
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);
/**
* @}
/* 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 *
}
}
+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
*/
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);
+}
+
/**
* @}
*/
}
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);
}