Hi Martin, On Oct 7, 2012, at 9:43 PM, Martin Desruisseaux wrote:
> Hello all > > This email is an explanation about two aspects in a recent commit that way be > worth explanation. The committed class is: > > https://builds.apache.org/job/sis-trunk/site/apidocs/org/apache/sis/math/MathFunctions.html > > > Multiple NaN values > ----------------- > Many developers know the java.lang.Double.NaN constant, but it may be less > known that there is actually thousands of different NaN values. All floating > values having a bit pattern in the [0x7F800001 ... 0x7FFFFFFF] or in the > [0xFF800001 ... 0xFFFFFFFF] ranges are NaN numbers. Some of them are > "signalling NaN", some of them may have their bit patterns changed by the > processor in an hardward-dependant way. However the [0x7FA00000 ... > 0x7FE00000] range seems stable at least on Inter processor. +1 makes sense. > > The coveage module (to be proposed to Apache SIS after metadata and > referencing) uses this trick for mixing "qualitative data" together with > "quantitative data" in a raster. Calculations involving quantitative data > like Sea Surface Temperature use the 'float' type. However those data are > often mixed with missing values because of clouds, lack of satellite data, > land surfaces, etc. Many software (including NetCDF file format) deal with > missing values by replacing them by a "pad value", often -9999. However such > practice may be dangerous: developers have to check for pad values in about > every corner of their code, otherwise a calculation mixing a real value with > a pad value will produce a wrong result (not necessarily in a way easy to > spot). Replacing all pad values by Float.NaN resolve this issue, but we lost > the differentiation between the causes of missing values (clouds, lands, > etc.). Yep we have seen this a bunch with remote sensing data a ton too. > > The MathFunctions.toNaNFloat(int) and toNaNOrdinal(float) methods try to give > the best of both worlds: true NaN numbers while encoding in them the cause of > missing data. However those methods probably need to be tested in a wider > spectrum of environments than other methods. +1 > > > Positive and negative zeros > ----------------------- > MathFunctions contains some functions for differentiating positive zero from > negative zero. We can not differentiate those two zeros with the usual <, >, > <=, >= or == operators, so we need again to look at the bits pattern (note > that Math.abs(float, float) and Math.abs(double, double) do that too). Most > of the time, we don't need to differentiate those two zeros. But one special > case is when dealing with an envelope crossing the anti-meridian in the way > described by the Web Coverage Service (WCS) specification. They are the red > box in the figure show on this page: > > http://www.geotoolkit.org/apidocs/org/geotoolkit/geometry/GeneralEnvelope.html > > The most tricky case occurs when the envelope goes from 0 to 360° of > longitude, which in the [-180 ... 180]° range is represented by [0 ... -0]°C. > The later range is different than [-0 ... 0]°C, which is an empty range. So > the GeneralEnvelope class need to be especially careful about the sign of > zero. The MathFunctions.isPositive(double), isNegative(double) and related > methods are there for this purpose. Ahhh yes, makes sense. Thanks for a great explanation, Martin! Cheers, Chris
