docs: static String preambleToString(final Memory mem) {
      final int preLongs = getAndCheckPreLongs(mem);
      final ResizeFactor rf = ResizeFactor.getRF(extractLgResizeFactor(mem));
      final int serVer = extractSerVer(mem);
      final Family family = Family.idToFamily(extractFamilyID(mem));
      final int lgNomLongs = extractLgNomLongs(mem);
      final int lgArrLongs = extractLgArrLongs(mem);
  
      //Flags
      final int flags = extractFlags(mem);
      final String flagsStr = zeroPad(Integer.toBinaryString(flags), 8) + ", " + (flags);
      final String nativeOrder = ByteOrder.nativeOrder().toString();
      final boolean bigEndian = (flags & BIG_ENDIAN_FLAG_MASK) > 0;
      final boolean readOnly = (flags & READ_ONLY_FLAG_MASK) > 0;
      final boolean empty = (flags & EMPTY_FLAG_MASK) > 0;
      final boolean compact = (flags & COMPACT_FLAG_MASK) > 0;
      final boolean ordered = (flags & ORDERED_FLAG_MASK) > 0;
      final boolean singleItem = !empty && (preLongs == 1);
  
      final int seedHash = extractSeedHash(mem);
  
      //assumes preLongs == 1; empty or singleItem
      int curCount = singleItem ? 1 : 0;
      float p = (float) 1.0;            //preLongs 1 or 2
      long thetaLong = Long.MAX_VALUE;  //preLongs 1 or 2
      long thetaULong = thetaLong;      //preLongs 1, 2 or 3
  
      if (preLongs == 2) { //exact (non-estimating) CompactSketch
        curCount = extractCurCount(mem);
        p = extractP(mem);
      }
      else if (preLongs == 3) { //Update Sketch
        curCount = extractCurCount(mem);
        p = extractP(mem);
        thetaLong = extractThetaLong(mem);
        thetaULong = thetaLong;
      }
      else if (preLongs == 4) { //Union
        curCount = extractCurCount(mem);
        p = extractP(mem);
        thetaLong = extractThetaLong(mem);
        thetaULong = extractUnionThetaLong(mem);
      }
      //else the same as an empty sketch or singleItem
  
      final double thetaDbl = thetaLong / MAX_THETA_LONG_AS_DOUBLE;
      final String thetaHex = zeroPad(Long.toHexString(thetaLong), 16);
      final double thetaUDbl = thetaULong / MAX_THETA_LONG_AS_DOUBLE;
      final String thetaUHex = zeroPad(Long.toHexString(thetaULong), 16);
  
      final StringBuilder sb = new StringBuilder();
      sb.append(LS);
      sb.append("### SKETCH PREAMBLE SUMMARY:").append(LS);
      sb.append("Byte  0: Preamble Longs       : ").append(preLongs).append(LS);
      sb.append("Byte  0: ResizeFactor         : ").append(rf.toString()).append(LS);
      sb.append("Byte  1: Serialization Version: ").append(serVer).append(LS);
      sb.append("Byte  2: Family               : ").append(family.toString()).append(LS);
      sb.append("Byte  3: LgNomLongs           : ").append(lgNomLongs).append(LS);
      sb.append("Byte  4: LgArrLongs           : ").append(lgArrLongs).append(LS);
      sb.append("Byte  5: Flags Field          : ").append(flagsStr).append(LS);
      sb.append("  (Native Byte Order)         : ").append(nativeOrder).append(LS);
      sb.append("  BIG_ENDIAN_STORAGE          : ").append(bigEndian).append(LS);
      sb.append("  READ_ONLY                   : ").append(readOnly).append(LS);
      sb.append("  EMPTY                       : ").append(empty).append(LS);
      sb.append("  COMPACT                     : ").append(compact).append(LS);
      sb.append("  ORDERED                     : ").append(ordered).append(LS);
      sb.append("  SINGLEITEM  (derived)       : ").append(singleItem).append(LS);
      sb.append("Bytes 6-7  : Seed Hash        : ").append(Integer.toHexString(seedHash)).append(LS);
      if (preLongs == 1) {
        sb.append(" --ABSENT, ASSUMED:").append(LS);
        sb.append("Bytes 8-11 : CurrentCount     : ").append(curCount).append(LS);
        sb.append("Bytes 12-15: P                : ").append(p).append(LS);
        sb.append("Bytes 16-23: Theta (double)   : ").append(thetaDbl).append(LS);
        sb.append("             Theta (long)     : ").append(thetaLong).append(LS);
        sb.append("             Theta (long,hex) : ").append(thetaHex).append(LS);
      }
      else if (preLongs == 2) {
        sb.append("Bytes 8-11 : CurrentCount     : ").append(curCount).append(LS);
        sb.append("Bytes 12-15: P                : ").append(p).append(LS);
        sb.append(" --ABSENT, ASSUMED:").append(LS);
        sb.append("Bytes 16-23: Theta (double)   : ").append(thetaDbl).append(LS);
        sb.append("             Theta (long)     : ").append(thetaLong).append(LS);
        sb.append("             Theta (long,hex) : ").append(thetaHex).append(LS);
      }
      else if (preLongs == 3) {
        sb.append("Bytes 8-11 : CurrentCount     : ").append(curCount).append(LS);
        sb.append("Bytes 12-15: P                : ").append(p).append(LS);
        sb.append("Bytes 16-23: Theta (double)   : ").append(thetaDbl).append(LS);
        sb.append("             Theta (long)     : ").append(thetaLong).append(LS);
        sb.append("             Theta (long,hex) : ").append(thetaHex).append(LS);
      }
      else { //preLongs == 4
        sb.append("Bytes 8-11 : CurrentCount     : ").append(curCount).append(LS);
        sb.append("Bytes 12-15: P                : ").append(p).append(LS);
        sb.append("Bytes 16-23: Theta (double)   : ").append(thetaDbl).append(LS);
        sb.append("             Theta (long)     : ").append(thetaLong).append(LS);
        sb.append("             Theta (long,hex) : ").append(thetaHex).append(LS);
        sb.append("Bytes 25-31: ThetaU (double)  : ").append(thetaUDbl).append(LS);
        sb.append("             ThetaU (long)    : ").append(thetaULong).append(LS);
        sb.append("             ThetaU (long,hex): ").append(thetaUHex).append(LS);
      }
      sb.append(  "Preamble Bytes                : ").append(preLongs * 8).append(LS);
      sb.append(  "Data Bytes                    : ").append(curCount * 8).append(LS);
      sb.append(  "TOTAL Sketch Bytes            : ").append(mem.getCapacity()).append(LS);
      sb.append("### END SKETCH PREAMBLE SUMMARY").append(LS);
      return sb.toString();
    }