[GRASS-dev] Re: [GRASS GIS] #1161: g.region and r.info decimel issue when using grass python libs

GRASS GIS trac at osgeo.org
Sun Oct 3 16:15:08 EDT 2010


#1161: g.region and r.info decimel issue when using grass python libs
-------------------------+--------------------------------------------------
  Reporter:  isaacullah  |       Owner:  grass-dev@…              
      Type:  defect      |      Status:  closed                   
  Priority:  normal      |   Milestone:  6.4.1                    
 Component:  Python      |     Version:  6.4.0                    
Resolution:  invalid     |    Keywords:                           
  Platform:  All         |         Cpu:  All                      
-------------------------+--------------------------------------------------

Comment(by glynn):

 Replying to [comment:5 cmbarton]:

 > Thanks for the explanation. The difference between the g.region
 representation to the shell and the information in the python dictionary
 does seem a result of lossy conversion (e.g., 4.9998993900000004).

 How did you determine what is really in the Python dictionary? Bear in
 mind that displaying the value in decimal typically performs another lossy
 conversion, and Python's decimal formatting behaviour is known to be
 suboptimal (i.e. it will typically use too many decimal places). E.g.:
 {{{
 > x = 5.1
 > x
 5.0999999999999996
 > str(x)
 '5.1'
 > repr(x)
 '5.0999999999999996'
 }}}

 Note that the longer version is probably closer to the exact decimal
 representation of the binary floating-point value, while the shorter
 version is probably the shortest decimal value which would convert to the
 given binary floating-point value.

 Or, more relevant to the original report:
 {{{
 > north = 4293588.60267
 > north
 4293588.6026699999
 > str(north)
 '4293588.60267'
 > repr(north)
 '4293588.6026699999'
 > '%f' % north
 '4293588.602670'
 > '%.5f' % north
 '4293588.60267'
 }}}

 > Maybe there is no solution to this, but it seems that g.region and
 grass.region() *ought* to be returning exactly the same values. At least,
 without knowing what you have explained, the normal assumption is that
 these would match.

 g.region returns strings; grass.script.region() returns numbers
 (specifically, Python "float"s, which on any modern system will be IEEE
 double-precision floating-point values). If you're going to be using those
 values for anything, they will get converted to floating-point at some
 point, and it's a safe bet that you will get exactly the same result
 regardless of whatever performs the conversion.

 > If we have Java (or perhaps our Python scripts) round grass.region()
 values to the maximum number of significant digits output to the shell, do
 you think we could be assured that the values would match exactly? If so,
 what about making this an optional argument (i.e, match g.region shell
 output) for grass.region(), grass.raster_info(), and other Python library
 functions that return region boundaries?

 Given that coordinates are limited by the circumference of the earth, both
 %.15g and %.8f should be converted without loss (i.e. adjacent values
 should have distinct floating-point representations), so if you format as
 decimal with the correct number of digits, you should get the original
 value. This has to be done when you convert to decimal, though; you can't
 "tag" floating-point values with formatting options.

 If you're comparing floating-point values, you should be comparing to
 within some tolerance. I'd suggest ten microns to allow for %.6f (which is
 the default for %f if no precision is given).

 On x86, it's impractical to perform exact comparisons for most floating
 point values, as the CPU uses 80 bits ("long double") internally but only
 64 bits if the value is stored in a "double", which means that "x = y; if
 (x == y) ..." can be false.

-- 
Ticket URL: <http://trac.osgeo.org/grass/ticket/1161#comment:6>
GRASS GIS <http://grass.osgeo.org>



More information about the grass-dev mailing list