dis_long_double_t disrl(int stream, int *retval) { int expon; unsigned uexpon; int locret; int negate; unsigned ndigs; unsigned nskips; dis_long_double_t ldval; assert(retval != NULL); assert(disr_commit != NULL); ldval = 0.0L; locret = disrl_(stream, &ldval, &ndigs, &nskips, LDBL_DIG, 1, 0); if (locret == DIS_SUCCESS) { locret = disrsi_(stream, &negate, &uexpon, 1, 0); if (locret == DIS_SUCCESS) { expon = negate ? nskips - uexpon : nskips + uexpon; if (expon + (int)ndigs > LDBL_MAX_10_EXP) { if (expon + (int)ndigs > LDBL_MAX_10_EXP + 1) { ldval = ldval < 0.0L ? -HUGE_VAL : HUGE_VAL; locret = DIS_OVERFLOW; } else { ldval *= disp10l_(expon - 1); if (ldval > LDBL_MAX / 10.0L) { ldval = ldval < 0.0L ? -HUGE_VAL : HUGE_VAL; locret = DIS_OVERFLOW; } else ldval *= 10.0L; } } else { if (expon < LDBL_MIN_10_EXP) { ldval *= disp10l_(expon + (int)ndigs); ldval /= disp10l_((int)ndigs); } else ldval *= disp10l_(expon); } } } if ((*disr_commit)(stream, locret == DIS_SUCCESS) < 0) locret = DIS_NOCOMMIT; *retval = locret; return (ldval); }
double disrd( struct tcp_chan *chan, int *retval) { int expon; unsigned uexpon; int locret; int negate; unsigned ndigs; unsigned nskips; dis_long_double_t ldval; assert(retval != NULL); ldval = 0.0L; locret = disrl_(chan, &ldval, &ndigs, &nskips, DBL_DIG, 1); if (locret == DIS_SUCCESS) { locret = disrsi_(chan, &negate, &uexpon, 1); if (locret == DIS_SUCCESS) { expon = negate ? nskips - uexpon : nskips + uexpon; if (expon + (int)ndigs > DBL_MAX_10_EXP) { if (expon + (int)ndigs > DBL_MAX_10_EXP + 1) { ldval = ldval < 0.0L ? -HUGE_VAL : HUGE_VAL; locret = DIS_OVERFLOW; } else { ldval *= disp10l_(expon - 1); if (ldval > DBL_MAX / 10.0L) { ldval = ldval < 0.0L ? -HUGE_VAL : HUGE_VAL; locret = DIS_OVERFLOW; } else ldval *= 10.0L; } } else { if (expon < LDBL_MIN_10_EXP) { ldval *= disp10l_(expon + (int)ndigs); ldval /= disp10l_((int)ndigs); } else ldval *= disp10l_(expon); } } } if (tcp_rcommit(chan, locret == DIS_SUCCESS) < 0) locret = DIS_NOCOMMIT; *retval = locret; return((double)ldval); }
/** * @brief * -Gets a Data-is-Strings floating point number from <stream> and converts * it into a long double and returns it. The number from <stream> consists of * two consecutive signed integers. The first is the coefficient, with its * implied decimal point at the low-order end. The second is the exponent * as a power of 10. * * @return int * @retval DIS_success/error status * */ int disrl_(int stream, dis_long_double_t *ldval, unsigned *ndigs, unsigned *nskips, unsigned sigd, unsigned count, int recursv) { int c; int negate; unsigned unum; char *cp; dis_long_double_t fpnum; assert(stream >= 0); assert(dis_getc != NULL); assert(disr_skip != NULL); if (++recursv > DIS_RECURSIVE_LIMIT) return (DIS_PROTO); /* dis_umaxd would be initialized by prior call to dis_init_tables */ switch (c = (*dis_getc)(stream)) { case '-': case '+': negate = c == '-'; *nskips = count > sigd ? count - sigd : 0; count -= *nskips; *ndigs = count; fpnum = 0.0L; do { if ((c = (*dis_getc)(stream)) < '0' || c > '9') { if (c < 0) return (DIS_EOD); return (DIS_NONDIGIT); } fpnum = fpnum * 10.0L + (dis_long_double_t)(c - '0'); } while (--count); if ((count = *nskips) > 0) { count--; switch ((*dis_getc)(stream)) { case '5': if (count == 0) break; case '6': case '7': case '8': case '9': fpnum += 1.0L; case '0': case '1': case '2': case '3': case '4': if (count > 0 && (*disr_skip)(stream, (size_t)count) == count) return (DIS_EOD); break; default: return (DIS_NONDIGIT); } } *ldval = negate ? -fpnum : fpnum; return (DIS_SUCCESS); case '0': return (DIS_LEADZRO); case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': unum = c - '0'; if (count > 1) { if (count > dis_umaxd) break; if ((*dis_gets)(stream, dis_buffer + 1, count - 1) != count - 1) return (DIS_EOD); cp = dis_buffer; if (count == dis_umaxd) { *cp = c; if (memcmp(dis_buffer, dis_umax, dis_umaxd) > 0) break; } while (--count) { if ((c = *++cp) < '0' || c > '9') return (DIS_NONDIGIT); unum = unum * 10 + (unsigned)(c - '0'); } } return (disrl_(stream, ldval, ndigs, nskips, sigd, unum, recursv)); case -1: return (DIS_EOD); case -2: return (DIS_EOF); default: return (DIS_NONDIGIT); } *ldval = HUGE_VAL; return (DIS_OVERFLOW); }