cdm/src/main/java/ucar/ma2/MAMath.java
public static MAMath.ScaleOffset calcScaleOffsetSkipMissingData(Array a, double missingValue, int nbits) {
    MAMath.MinMax minmax = getMinMaxSkipMissingData(a, missingValue);

    if (a.isUnsigned()) {
      long size = (1L << nbits) - 1;
      double offset = minmax.min;
      double scale =(minmax.max - minmax.min) / size;
      return new ScaleOffset(scale, offset);

    } else {
      long size = (1L << nbits) - 2;
      double offset = (minmax.max + minmax.min) / 2;
      double scale =(minmax.max - minmax.min) / size;
      return new ScaleOffset(scale, offset);
    }
  }
public static MAMath.ScaleOffset calcScaleOffsetSkipMissingData(Array a, double missingValue, int nbits) {
    MAMath.MinMax minmax = getMinMaxSkipMissingData(a, missingValue);

    if (a.isUnsigned()) {
      long size = (1L << nbits) - 1;
      double offset = minmax.min;
      double scale =(minmax.max - minmax.min) / size;
      return new ScaleOffset(scale, offset);

    } else {
      long size = (1L << nbits) - 2;
      double offset = (minmax.max + minmax.min) / 2;
      double scale =(minmax.max - minmax.min) / size;
      return new ScaleOffset(scale, offset);
    }
  }
Calculate the scale/offset for an array of numbers.
<pre>
If signed:
then
max value unpacked = 2^(n-1) - 1 packed
min value unpacked = -(2^(n-1) - 1) packed
note that -2^(n-1) is unused, and a good place to map missing values
by solving 2 eq in 2 unknowns, we get:
scale = (max - min) / (2^n - 2)
offset = (max + min) / 2
If unsigned then
max value unpacked = 2^n - 1 packed
min value unpacked = 0 packed
and:
scale = (max - min) / (2^n - 1)
offset = min
One could modify this to allow a holder for missing values.
</pre>
@param a array to convert (not changed)
@param missingValue skip these
@param nbits map into this many bits
@return ScaleOffset, calculated as above.