Skip to content

Format floating point numbers in output d-paths#225

Closed
ohnorobo wants to merge 3 commits intomathandy:masterfrom
ohnorobo:floating_point_noise
Closed

Format floating point numbers in output d-paths#225
ohnorobo wants to merge 3 commits intomathandy:masterfrom
ohnorobo:floating_point_noise

Conversation

@ohnorobo
Copy link
Copy Markdown
Contributor

@ohnorobo ohnorobo commented Jul 4, 2024

Format the floating point numbers output by Path.d to avoid a bunch of .x0000000000001 and .x999999999999 noise. Fixes #223.

Changed behavior:

  • Numbers with small errors introduced by their floating point representation are output correctly. ex 12.870000000000001 -> 12.87, 64.13999999999999 -> 64.14

  • Whole numbers which were emitted with a trailing 0 now have no trailing 0. ex: 2.0 -> 2. This required some changes in the existing test cases. The output now more closely matches the way numbers are represented in the SVG spec examples. It's easiest to see this in the changes to test.test_generation.TestGeneration.test_path_parsing.

  • Some small floating point numbers now emit fewer significant digits. ex: 206.07112 -> 206.071 in test.test_groups.TestGroups.test_add_group. This is chosen by python's idea of which representation is the 'best' as explained here

This change also removes the need for special python2/3 casing in test.test_generation.TestGeneration.test_path_parsing since the behavior of g is the same in both. It may be possible to further simplify this test.

@faisalakhlaq
Copy link
Copy Markdown

Seems like there is no one merging the PRs?

@mathandy
Copy link
Copy Markdown
Owner

mathandy commented May 8, 2025

Thanks for the PR @ohnorobo, I think it's a tempting idea, I certainly dislike the representation error and am open to solutions. That said, I think the solution should work for 15 digit decimals -- I think all representable 15 digit decimals can be converted to IEEE doubles and back without error (wikipedia reference).

This solutions seems pretty aggressive, e.g.

In [1]: 'M {}'.format(64.13999)
Out[1]: 'M 64.13999'

In [2]: 'M {:g}'.format(64.13999)  # using g rounds pretty aggressively
Out[2]: 'M 64.14'

svgpathtools is intended for mathematical analysis of data stored as svg paths. For this reason, I don't think it would suit the primary customer base to round so aggressively.

If you have a good argument or other reason, please feel free to re-open this PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Reading in dpaths introduces a lot of floating point approximation noise

3 participants