<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  </head>
  <body text="#000000" bgcolor="#FFFFFF">
    <div class="moz-cite-prefix">On 07/06/2018 07:14 AM, Even Rouault
      wrote:<br>
    </div>
    <blockquote type="cite" cite="mid:6868642.acaTliTEoa@even-i700">
      <blockquote type="cite" style="color: #000000;">
        <pre wrap="">  NoData Value=3.40282346638529011e+38
  Metadata:
    STATISTICS_MAXIMUM=3.4028234663853e+38
</pre>
      </blockquote>
      <pre wrap="">ok, the issue is that nodata value (stored as text in GeoTIFF) is slightly 
above the maximum value of a float32. Presumably due to rounding issues when 
formatting it. I've pushed a fix to detect that situation and clamp it to the 
max value of float32. A bit strange that the issue wasn't found on Windows 
though.</pre>
    </blockquote>
    A wider issue is that if the NoData value is not a
    fully-representable integer, you can't expect a direct comparison to
    work every time.  You also can't expect the text-encoded NoData
    value to match the binary value exactly, since people do silly
    things like truncate the precision or generate 'float' values using
    'double' computations.  The following C program:<br>
    <br>
    <tt>#include <stdio.h><br>
      #include <stdlib.h><br>
      #include <math.h><br>
      #include <float.h><br>
      int main() {<br>
          float f = (float) atof("3.40282346638529011e+38");<br>
          double d = 3.40282346638529011e+38;<br>
          long double e = 3.40282346638529011e+38L;<br>
          printf( "float:   %.18g  (%.18g, eq=%d)\n", f, (float)
      FLT_MAX,<br>
                   f == FLT_MAX );<br>
          printf( "double:  %.18g (%.18g)\n", d, (double) (float)
      FLT_MAX );<br>
          printf( "ldouble: %.19Lg (%.19Lg)\n", e, powl(2, 128) - 1 );<br>
          return( 0 );<br>
      }<br>
    </tt><br>
    produces the output on Linux/GCC of:<br>
    <br>
    <tt>float:   3.4028234663852886e+38  (3.4028234663852886e+38, eq=1)<br>
      double:  3.40282346638529011e+38 (3.4028234663852886e+38)<br>
      ldouble: 3.40282346638529011e+38 (3.402823669209384635e+38)</tt><br>
    <br>
    Which means the given NoData value doesn't actually overflow the
    'float' representation and I get an equality when executing the
    comparison using 'float's.  The given value here is presumably meant
    to be 2^128-1, though it doesn't match this at any precision.  The
    text is representable as a 'double' but not as 'float', which
    indicates some kind of tortured origin story.<br>
    <br>
    I don't know how GDAL does the comparison, but it needs to be done
    carefully.  In general, 'float's only keep 6 digits of accuracy when
    converting from decimal → binary → decimal and need 9 decimal digits
    to represent every conversion of binary → decimal → binary.  I do
    comparisons in my own code using 'double's after running the NoData
    value through 'float' and back again in this case and then use a
    comparison tolerance of ±(NoData × 1e-7) for 'float' samples (maybe
    it should be 1e-6 to handle more arbitrary precision truncations).<br>
    <br>
    With the available information, if GDAL did the comparison using
    'float's, the (float) STATISTICS_MAXIMUM == FLT_MAX == (float)
    3.40282346638529011e+38 and the NoData value would be detected
    properly.  If, OTOH, GDAL is representing NoData as 'double' and
    comparing this directly to 'float' samples, then the values wouldn't
    match, because the NoData text value does not match (double)
    FLT_MAX.<tt><br>
      <br>
    </tt>
    <div class="moz-signature">-- <br>
      Dr. Craig S. Bruce
      <br>
      Senior Software Developer
      <br>
      CubeWerx<i> </i>Inc.
      <br>
      <a href="http://www.cubewerx.com/">http://www.cubewerx.com</a></div>
  </body>
</html>