Index: ossp-pkg/xds/xds_engine_xdr.c RCS File: /v/ossp/cvs/ossp-pkg/xds/xds_engine_xdr.c,v rcsdiff -q -kk '-r1.8' '-r1.9' -u '/v/ossp/cvs/ossp-pkg/xds/xds_engine_xdr.c,v' 2>/dev/null --- 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; } /*