--- xds_engine_xdr.c 2001/08/23 08:42:50 1.8
+++ xds_engine_xdr.c 2001/08/30 10:42:09 1.9
@@ -299,15 +299,14 @@
typedef struct
{
- unsigned int sign :1;
- unsigned int fraction :23;
- int exponent :8;
+ xds_uint8_t sign :1;
+ xds_uint32_t fraction :23;
+ xds_int8_t exponent :8;
}
myfloat_t;
static int float2myfloat(myfloat_t* new_num, float num)
{
- const static unsigned int base = 2;
size_t i;
float tmp;
@@ -323,10 +322,10 @@
/* Determine the sign of the number. */
- if (num < 0)
+ if (num < 0.0)
{
new_num->sign = 1;
- num = 0 - num;
+ num = 0.0 - num;
}
else
new_num->sign = 0;
@@ -334,22 +333,22 @@
/* Canonify the number before we convert it. */
new_num->exponent = 0;
- while (num < 1)
+ while (num < 1.0)
{
- num *= base;
+ num *= 2.0;
--new_num->exponent;
}
/* Find the exponent. */
- for (i = 0, tmp = 1; i <= 128; ++i, tmp *= base)
+ for (i = 0, tmp = 1.0; i <= 128; ++i, tmp *= 2.0)
{
- if (tmp*base > num)
+ if (tmp * 2.0 > num)
break;
}
if (i <= 128)
{
- num = num / tmp - 1;
+ num = num / tmp - 1.0;
new_num->exponent += i;
}
else
@@ -359,17 +358,14 @@
for (new_num->fraction = 0, i = 0; i < 23; ++i)
{
- new_num->fraction *= base;
- if (num >= 1.0 / base)
+ new_num->fraction *= 2.0;
+ if (num >= 1.0 / 2.0)
{
- new_num->fraction |= 1;
- num = num * base - 1;
+ new_num->fraction += 1.0;
+ num = num * 2.0 - 1.0;
}
else
- {
- new_num->fraction |= 0;
- num *= base;
- }
+ num *= 2.0;
}
return 0;
@@ -419,12 +415,12 @@
value = va_arg(*args, float*);
*value = 0.0;
+ sign = (((xds_uint8_t*)buffer)[0] & 0x80) >> 7;
+ exponent = (((xds_uint8_t*)buffer)[0] & 0x7f) << 1;
+ exponent += (((xds_uint8_t*)buffer)[1] & 0x80) >> 7;
fraction = (((xds_uint8_t*)buffer)[1] & 0x7fffff) << 16;
fraction += ((xds_uint8_t*)buffer)[2] << 8;
fraction += ((xds_uint8_t*)buffer)[3];
- exponent = (((xds_uint8_t*)buffer)[0] & 0x7f) << 1;
- exponent += (((xds_uint8_t*)buffer)[1] & 0x80) >> 7;
- sign = (((xds_uint8_t*)buffer)[0] & 0x80) >> 7;
if (fraction == 0 && exponent == 0)
return XDS_OK;
@@ -432,11 +428,11 @@
for (i = 23; i > 0; --i)
{
if ((fraction & 0x01) == 1)
- *value += 1;
+ *value += 1.0;
*value /= 2.0;
- fraction /= 2;
+ fraction /= 2.0;
}
- *value += 1;
+ *value += 1.0;
if (exponent > 127)
{
@@ -460,20 +456,167 @@
* Encode/decode double-precision floating point values.
*/
+typedef struct
+ {
+ xds_uint8_t sign :1;
+ xds_uint64_t fraction :52;
+ xds_int16_t exponent :11;
+ }
+mydouble_t;
+
+static int double2mydouble(mydouble_t* new_num, double num)
+ {
+ size_t i;
+ double tmp;
+
+ /* Handle zero as a special case. */
+
+ if (num == 0.0)
+ {
+ new_num->sign = 0;
+ new_num->fraction = 0;
+ new_num->exponent = -1023;
+ return 0;
+ }
+
+ /* Determine the sign of the number. */
+
+ if (num < 0.0)
+ {
+ new_num->sign = 1;
+ num = 0.0 - num;
+ }
+ else
+ new_num->sign = 0;
+
+ /* Canonify the number before we convert it. */
+
+ new_num->exponent = 0;
+ while (num < 1.0)
+ {
+ num *= 2.0;
+ --new_num->exponent;
+ }
+
+ /* Find the exponent. */
+
+ for (i = 0, tmp = 1.0; i <= 1024; ++i, tmp *= 2.0)
+ {
+ if (tmp * 2.0 > num)
+ break;
+ }
+ if (i <= 1024)
+ {
+ num = num / tmp - 1.0;
+ new_num->exponent += i;
+ }
+ else
+ return 1;
+
+ /* Calculate the fraction part. */
+
+ for (new_num->fraction = 0, i = 0; i < 52; ++i)
+ {
+ new_num->fraction *= 2.0;
+ if (num >= 1.0 / 2.0)
+ {
+ new_num->fraction += 1.0;
+ num = num * 2.0 - 1.0;
+ }
+ else
+ num *= 2.0;
+ }
+
+ return 0;
+ }
+
+
int xdr_encode_double(xds_t *xds, void *engine_context,
- void *buffer, size_t buffer_size,
- size_t *used_buffer_size, va_list *args)
+ void *buffer, size_t buffer_size,
+ size_t *used_buffer_size, va_list *args)
{
- /* XXX */
- return -1;
+ mydouble_t value;
+ xds_uint16_t tmp;
+
+ xds_init_encoding_engine(8);
+
+ /* Get value and format it into the structure. */
+ double2mydouble(&value, va_arg(*args, double));
+
+ memset(buffer, 0, 8);
+
+ if (value.sign == 1)
+ ((xds_uint8_t*)buffer)[0] |= 0x80;
+
+ tmp = value.exponent + 1023;
+ ((xds_uint8_t*)buffer)[0] |= (tmp >> 4) & 0x7f;
+ ((xds_uint8_t*)buffer)[1] |= (tmp & 0x0f) << 4;
+
+ ((xds_uint8_t*)buffer)[1] |= (xds_uint8_t)((value.fraction & 0x0f000000000000) >> 48);
+ ((xds_uint8_t*)buffer)[2] |= (xds_uint8_t)((value.fraction & 0x00ff0000000000) >> 40);
+ ((xds_uint8_t*)buffer)[3] |= (xds_uint8_t)((value.fraction & 0x0000ff00000000) >> 32);
+ ((xds_uint8_t*)buffer)[4] |= (xds_uint8_t)((value.fraction & 0x000000ff000000) >> 24);
+ ((xds_uint8_t*)buffer)[5] |= (xds_uint8_t)((value.fraction & 0x00000000ff0000) >> 16);
+ ((xds_uint8_t*)buffer)[6] |= (xds_uint8_t)((value.fraction & 0x0000000000ff00) >> 8);
+ ((xds_uint8_t*)buffer)[7] |= (xds_uint8_t)((value.fraction & 0x000000000000ff) >> 0);
+
+ return XDS_OK;
}
int xdr_decode_double(xds_t *xds, void *engine_context,
- void *buffer, size_t buffer_size,
- size_t *used_buffer_size, va_list *args)
+ void *buffer, size_t buffer_size,
+ size_t *used_buffer_size, va_list *args)
{
- /* XXX */
- return -1;
+ double* value;
+ xds_uint64_t fraction;
+ xds_uint16_t exponent;
+ size_t i;
+ char sign;
+
+ xds_init_decoding_engine(8);
+
+ value = va_arg(*args, double*);
+ *value = 0.0;
+
+ sign = (((xds_uint8_t*)buffer)[0] & 0x80) >> 7;
+ exponent = (((xds_uint8_t*)buffer)[0] & 0x7f) << 4;
+ exponent += (((xds_uint8_t*)buffer)[1] & 0xf0) >> 4;
+
+ fraction = (xds_uint64_t)((((xds_uint8_t*)buffer)[1] & 0x0f)) << 48;
+ fraction += (xds_uint64_t)(((xds_uint8_t*)buffer)[2]) << 40;
+ fraction += (xds_uint64_t)(((xds_uint8_t*)buffer)[3]) << 32;
+ fraction += (xds_uint64_t)(((xds_uint8_t*)buffer)[4]) << 24;
+ fraction += (xds_uint64_t)(((xds_uint8_t*)buffer)[5]) << 16;
+ fraction += (xds_uint64_t)(((xds_uint8_t*)buffer)[6]) << 8;
+ fraction += (xds_uint64_t)(((xds_uint8_t*)buffer)[7]) << 0;
+
+ if (fraction == 0 && exponent == 0)
+ return XDS_OK;
+
+ for (i = 52; i > 0; --i)
+ {
+ if ((fraction & 0x01) == 1)
+ *value += 1.0;
+ *value /= 2.0;
+ fraction /= 2.0;
+ }
+ *value += 1.0;
+
+ if (exponent > 1023)
+ {
+ for (exponent -= 1023; exponent > 0; --exponent)
+ *value *= 2.0;
+ }
+ else
+ {
+ for (exponent = 1023 - exponent; exponent > 0; --exponent)
+ *value /= 2.0;
+ }
+
+ if (sign == 1)
+ *value = 0.0 - *value;
+
+ return XDS_OK;
}
/*
|