code: public double getRank(final double value) {
      if (isEmpty()) { return Double.NaN; }
      final DoublesSketchAccessor samples = DoublesSketchAccessor.wrap(this);
      long total = 0;
      int weight = 1;
      samples.setLevel(DoublesSketchAccessor.BB_LVL_IDX);
      for (int i = 0; i < samples.numItems(); i++) {
        if (samples.get(i) < value) {
          total += weight;
        }
      }
      long bitPattern = getBitPattern();
      for (int lvl = 0; bitPattern != 0L; lvl++, bitPattern >>>= 1) {
        weight *= 2;
        if ((bitPattern & 1L) > 0) { // level is not empty
          samples.setLevel(lvl);
          for (int i = 0; i < samples.numItems(); i++) {
            if (samples.get(i) < value) {
              total += weight;
            } else {
              break; // levels are sorted, no point comparing further
            }
          }
        }
      }
      return (double) total / getN();
    }
docs: Returns an approximation to the normalized (fractional) rank of the given value from 0 to 1
  inclusive.
  
  <p>The resulting approximation has a probabilistic guarantee that be obtained from the
  getNormalizedRankError(false) function.
  
  <p>If the sketch is empty this returns NaN.</p>
  
  @param value to be ranked
  @return an approximate rank of the given value