| 17451 | } |
| 17452 | |
| 17453 | inline void grisu2_round(char* buf, int len, std::uint64_t dist, std::uint64_t delta, |
| 17454 | std::uint64_t rest, std::uint64_t ten_k) |
| 17455 | { |
| 17456 | JSON_ASSERT(len >= 1); |
| 17457 | JSON_ASSERT(dist <= delta); |
| 17458 | JSON_ASSERT(rest <= delta); |
| 17459 | JSON_ASSERT(ten_k > 0); |
| 17460 | |
| 17461 | // <--------------------------- delta ----> |
| 17462 | // <---- dist ---------> |
| 17463 | // --------------[------------------+-------------------]-------------- |
| 17464 | // M- w M+ |
| 17465 | // |
| 17466 | // ten_k |
| 17467 | // <------> |
| 17468 | // <---- rest ----> |
| 17469 | // --------------[------------------+----+--------------]-------------- |
| 17470 | // w V |
| 17471 | // = buf * 10^k |
| 17472 | // |
| 17473 | // ten_k represents a unit-in-the-last-place in the decimal representation |
| 17474 | // stored in buf. |
| 17475 | // Decrement buf by ten_k while this takes buf closer to w. |
| 17476 | |
| 17477 | // The tests are written in this order to avoid overflow in unsigned |
| 17478 | // integer arithmetic. |
| 17479 | |
| 17480 | while (rest < dist |
| 17481 | && delta - rest >= ten_k |
| 17482 | && (rest + ten_k < dist || dist - rest > rest + ten_k - dist)) |
| 17483 | { |
| 17484 | JSON_ASSERT(buf[len - 1] != '0'); |
| 17485 | buf[len - 1]--; |
| 17486 | rest += ten_k; |
| 17487 | } |
| 17488 | } |
| 17489 | |
| 17490 | /*! |
| 17491 | Generates V = buffer * 10^decimal_exponent, such that M- <= V <= M+. |