docs: static boolean grisu3(double v, FastDtoaBuilder buffer) {
          long bits = Double.doubleToLongBits(v);
          DiyFp w = DoubleHelper.asNormalizedDiyFp(bits);
          // boundary_minus and boundary_plus are the boundaries between v and its
          // closest floating-point neighbors. Any number strictly between
          // boundary_minus and boundary_plus will round to v when convert to a double.
          // Grisu3 will never output representations that lie exactly on a boundary.
          DiyFp boundary_minus = new DiyFp(), boundary_plus = new DiyFp();
          DoubleHelper.normalizedBoundaries(bits, boundary_minus, boundary_plus);
          assert(boundary_plus.e() == w.e());
          DiyFp ten_mk = new DiyFp();  // Cached power of ten: 10^-k
          int mk =  CachedPowers.getCachedPower(w.e() + DiyFp.kSignificandSize,
                  minimal_target_exponent, maximal_target_exponent, ten_mk);
          assert(minimal_target_exponent <= w.e() + ten_mk.e() +
                  DiyFp.kSignificandSize &&
                  maximal_target_exponent >= w.e() + ten_mk.e() +
                          DiyFp.kSignificandSize);
          // Note that ten_mk is only an approximation of 10^-k. A DiyFp only contains a
          // 64 bit significand and ten_mk is thus only precise up to 64 bits.
  
          // The DiyFp::Times procedure rounds its result, and ten_mk is approximated
          // too. The variable scaled_w (as well as scaled_boundary_minus/plus) are now
          // off by a small amount.
          // In fact: scaled_w - w*10^k < 1ulp (unit in the last place) of scaled_w.
          // In other words: let f = scaled_w.f() and e = scaled_w.e(), then
          //           (f-1) * 2^e < w*10^k < (f+1) * 2^e
          DiyFp scaled_w = DiyFp.times(w, ten_mk);
          assert(scaled_w.e() ==
                  boundary_plus.e() + ten_mk.e() + DiyFp.kSignificandSize);
          // In theory it would be possible to avoid some recomputations by computing
          // the difference between w and boundary_minus/plus (a power of 2) and to
          // compute scaled_boundary_minus/plus by subtracting/adding from
          // scaled_w. However the code becomes much less readable and the speed
          // enhancements are not terriffic.
          DiyFp scaled_boundary_minus = DiyFp.times(boundary_minus, ten_mk);
          DiyFp scaled_boundary_plus  = DiyFp.times(boundary_plus,  ten_mk);
  
          // DigitGen will generate the digits of scaled_w. Therefore we have
          // v == (double) (scaled_w * 10^-mk).
          // Set decimal_exponent == -mk and pass it to DigitGen. If scaled_w is not an
          // integer than it will be updated. For instance if scaled_w == 1.23 then
          // the buffer will be filled with "123" und the decimal_exponent will be
          // decreased by 2.
          return digitGen(scaled_boundary_minus, scaled_w, scaled_boundary_plus,
                  buffer, mk);
      }