tkrajina/gpxpy

Bug in float to string conversion

BenediktO opened this issue · 0 comments

I found a bug in the file gpxpy.utils in the function make_str().

Look at the following code:

import gpxpy.gpx

gpx = gpxpy.gpx.GPX()
gpx.waypoints.append(gpxpy.gpx.GPXWaypoint(latitude=10000000000000000.0, longitude=10000000000000000.0, elevation=10000000000000000.0))
with open('bug.gpx', 'w') as f:
    f.write(gpx.to_xml())

This produces the following output in bug.gpx:

<?xml version="1.0" encoding="UTF-8"?>
<gpx xmlns="http://www.topografix.com/GPX/1/1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd" version="1.1" creator="gpx.py -- https://github.com/tkrajina/gpxpy">
  <wpt lat="1" lon="1">
    <ele>1</ele>
  </wpt>
</gpx>

Where all the values are now 1 and not 10000000000000000.

I know this example is ridiculous but the affected function make_str() is used often and such a problem might occur in other places.
Looking at utils.py:77 one can trace the origin:

>>> s = 10000000000000000.0
>>> str(s)
'1e+16' # scientific notation not allowed
>>> format(s, '.10f')
'10000000000000000.0000000000'
>>> format(s, '.10f').rstrip('0.') # problem
'1'
>>> format(s, '.10f').rstrip('0').rstrip('.') # workaround
'10000000000000000'

The strip function matches any of the given characters and thus removes the 0's before the decimal point.

One solution would be to use the proposition mentioned here which only can remove zeros after the decimal point.

I know it might not seem super important but I think this should be fixed nevertheless.