docs: public void shiftValuesRight(final int numberOfBinaryOrdersOfMagnitude) {
          if (numberOfBinaryOrdersOfMagnitude < 0) {
              throw new IllegalArgumentException("Cannot shift by a negative number of magnitudes");
          }
  
          if (numberOfBinaryOrdersOfMagnitude == 0) {
              return;
          }
          if (getTotalCount() == getCountAtIndex(0)) {
              // (no need to shift any values if all recorded values are at the 0 value level:)
              return;
          }
  
          final int shiftAmount = subBucketHalfCount * numberOfBinaryOrdersOfMagnitude;
  
          // indicate underflow if minValue is in the range being shifted from:
          int minNonZeroValueIndex = countsArrayIndex(getMinNonZeroValue());
          // Any shifting into the bottom-most half bucket would represents a loss of accuracy,
          // and a non-reversible operation. Therefore any non-0 value that falls in an
          // index below (shiftAmount + subBucketHalfCount) would represent an underflow:
          if (minNonZeroValueIndex < shiftAmount + subBucketHalfCount) {
              throw new ArrayIndexOutOfBoundsException(
                      "Operation would underflow and lose precision of already recorded value counts");
          }
  
          // perform shift:
  
          long maxValueBeforeShift = maxValueUpdater.getAndSet(this, 0);
          long minNonZeroValueBeforeShift = minNonZeroValueUpdater.getAndSet(this, Long.MAX_VALUE);
  
          // move normalizingIndexOffset
          shiftNormalizingIndexByOffset(-shiftAmount, false);
  
          // adjust min, max:
          updateMinAndMax(maxValueBeforeShift >> numberOfBinaryOrdersOfMagnitude);
          if (minNonZeroValueBeforeShift < Long.MAX_VALUE) {
              updateMinAndMax(minNonZeroValueBeforeShift >> numberOfBinaryOrdersOfMagnitude);
          }
      }