// Path: java/com/google/zetasketch/IncompatiblePrecisionException.java
// public class IncompatiblePrecisionException extends IllegalArgumentException {
//   public IncompatiblePrecisionException(String message) {
//     super(message);
//   }
// 
//   private static final long serialVersionUID = 0;
// }


import com.google.zetasketch.IncompatiblePrecisionException;
import it.unimi.dsi.fastutil.ints.AbstractIntIterator;
import it.unimi.dsi.fastutil.ints.IntIterator;
import java.util.NoSuchElementException;
import java.util.Objects;
import javax.annotation.Nullable;
          : "normal precision must be between 1 and 24 (inclusive)";
      // While for the sparse precision it is 31 - 1 (for flag).
      assert 1 <= sparsePrecision && sparsePrecision <= 30
          : "sparse precision must be between 1 and 30 (inclusive)";
      assert sparsePrecision >= normalPrecision
          : "sparse precision must be larger than or equal to the normal precision";

      this.normalPrecision = normalPrecision;
      this.sparsePrecision = sparsePrecision;

      // The position of the flag needs to be larger than any bits that could be used in the rhoW or
      // non-rhoW encoded values so that (a) the two values can be distinguished and (b) they will
      // not interleave when sorted numerically.
      rhoEncodedFlag = 1 << Math.max(sparsePrecision, normalPrecision + RHOW_BITS);

      this.normal = new Normal(normalPrecision);
    }

    /**
     * Checks whether a sparse encoding is compatible with another. This encoding's precision and
     * sparsePrecision must be both smaller or equal, or both bigger or equal to the {@code other}
     * Encoding's precisions for them to be compatible.
     */
    public void assertCompatible(Sparse other) {
      if ((this.normalPrecision <= other.normalPrecision
              && this.sparsePrecision <= other.sparsePrecision)
          || (this.normalPrecision >= other.normalPrecision
              && this.sparsePrecision >= other.sparsePrecision)) {
        return;
      }
// Path: java/com/google/zetasketch/IncompatiblePrecisionException.java
// public class IncompatiblePrecisionException extends IllegalArgumentException {
//   public IncompatiblePrecisionException(String message) {
//     super(message);
//   }
// 
//   private static final long serialVersionUID = 0;
// }


// Path: java/com/google/zetasketch/internal/hllplus/Encoding.java
import com.google.zetasketch.IncompatiblePrecisionException;
import it.unimi.dsi.fastutil.ints.AbstractIntIterator;
import it.unimi.dsi.fastutil.ints.IntIterator;
import java.util.NoSuchElementException;
import java.util.Objects;
import javax.annotation.Nullable;

          : "normal precision must be between 1 and 24 (inclusive)";
      // While for the sparse precision it is 31 - 1 (for flag).
      assert 1 <= sparsePrecision && sparsePrecision <= 30
          : "sparse precision must be between 1 and 30 (inclusive)";
      assert sparsePrecision >= normalPrecision
          : "sparse precision must be larger than or equal to the normal precision";

      this.normalPrecision = normalPrecision;
      this.sparsePrecision = sparsePrecision;

      // The position of the flag needs to be larger than any bits that could be used in the rhoW or
      // non-rhoW encoded values so that (a) the two values can be distinguished and (b) they will
      // not interleave when sorted numerically.
      rhoEncodedFlag = 1 << Math.max(sparsePrecision, normalPrecision + RHOW_BITS);

      this.normal = new Normal(normalPrecision);
    }

    /**
     * Checks whether a sparse encoding is compatible with another. This encoding's precision and
     * sparsePrecision must be both smaller or equal, or both bigger or equal to the {@code other}
     * Encoding's precisions for them to be compatible.
     */
    public void assertCompatible(Sparse other) {
      if ((this.normalPrecision <= other.normalPrecision
              && this.sparsePrecision <= other.sparsePrecision)
          || (this.normalPrecision >= other.normalPrecision
              && this.sparsePrecision >= other.sparsePrecision)) {
        return;
      }
      throw new IncompatiblePrecisionException(