in include/yyjson/yyjson.c [4231:4280]
static_noinline void bigint_set_buf(bigint *big, u64 sig, i32 *exp,
u8 *sig_cut, u8 *sig_end, u8 *dot_pos) {
if (unlikely(!sig_cut)) {
/* no digit cut, set significant part only */
bigint_set_u64(big, sig);
return;
} else {
/* some digits were cut, read them from 'sig_cut' to 'sig_end' */
u8 *hdr = sig_cut;
u8 *cur = hdr;
u32 len = 0;
u64 val = 0;
bool dig_big_cut = false;
bool has_dot = (hdr < dot_pos) & (dot_pos < sig_end);
u32 dig_len_total = U64_SAFE_DIG + (u32)(sig_end - hdr) - has_dot;
sig -= (*sig_cut >= '5'); /* sig was rounded before */
if (dig_len_total > F64_MAX_DEC_DIG) {
dig_big_cut = true;
sig_end -= dig_len_total - (F64_MAX_DEC_DIG + 1);
sig_end -= (dot_pos + 1 == sig_end);
dig_len_total = (F64_MAX_DEC_DIG + 1);
}
*exp -= (i32)dig_len_total - U64_SAFE_DIG;
big->used = 1;
big->bits[0] = sig;
while (cur < sig_end) {
if (likely(cur != dot_pos)) {
val = val * 10 + (u8)(*cur++ - '0');
len++;
if (unlikely(cur == sig_end && dig_big_cut)) {
/* The last digit must be non-zero, */
/* set it to '1' for correct rounding. */
val = val - (val % 10) + 1;
}
if (len == U64_SAFE_DIG || cur == sig_end) {
bigint_mul_pow10(big, (i32)len);
bigint_add_u64(big, val);
val = 0;
len = 0;
}
} else {
cur++;
}
}
}
}