+/* Round to even with given precision. Extra digits are not zeroed. */
+static uint32_t nd_round(uint32_t* nd, uint32_t ndlo, uint32_t ndhi, int32_t e)
+{
+ uint32_t i;
+ int32_t d;
+ char buf[9];
+ if (e >= 0) {
+ i = (uint32_t)e / 9;
+ d = 8 - e + (int32_t)i * 9;
+ } else {
+ int32_t f = (e - 8) / 9;
+ i = (uint32_t)(64 + f);
+ d = 8 - e + f * 9;
+ }
+ lj_strfmt_wuint9(buf, nd[i]);
+ if (buf[d] < '5') {
+ return ndhi; /* Don't round up. */
+ } else if (buf[d] == '5') { /* Must check for round to even. */
+ if (d ? (buf[d-1] & 1) : (nd[(i + 1) & 0x3f] & 1))
+ goto round_up; /* Round up '[13579]5.*' */
+ while (++d < 9) { /* Check remaining digits in buffer. */
+ if (buf[d] != '0')
+ goto round_up; /* Round up '[02468]5[^0]*'. */
+ }
+ while (i != ndlo) { /* Check remaining fraction. */
+ if (nd[i])
+ goto round_up; /* Round up '[02468]5[^0]*'. */
+ i = (i - 1) & 0x3f;
+ }
+ return ndhi; /* Don't round up. */
+ } /* else: round up.*/
+round_up:
+ return nd_add_m10e(nd, ndhi, 5, e); /* Round up by adding 5*10^e. */
+}
+