glotzerlab / signac-docs

Documentation for the signac framework.
https://docs.signac.io/
BSD 3-Clause "New" or "Revised" License
8 stars 18 forks source link

support serialization of fixed point numbers #9

Open csadorf opened 6 years ago

csadorf commented 6 years ago

Original report by Jens Glaser (Bitbucket: jens_glaser, GitHub: jglaser).


Currently, serialization of float()'s into JSON state points can some times result in unwieldy floating point numbers with a lot of extra digits that approximate the intended number. This is particularly annoying when one wants to later retrieve those numbers with a program outside python that doesn't allow iterating over state points (e.g. using a view/the filesystem).

Example: 0.33999999999999997 instead of 0.34

This issue arises when constructing floating point state points of the form y = i*x + y0, where i is some integer and x is an increment. It looks like the issue can be solved if we use python's fixed point arithmetic. Currently, that doesn't serialize to JSON, but it could be subclassed to serialize to an 'exact' float.

The attached example demonstrates how it would work.

signac init my_project
python floating_point.py
signac find | xargs signac state point
csadorf commented 6 years ago

Original comment by Carl Simon Adorf (Bitbucket: csadorf, GitHub: csadorf).


I'm going to paste the slightly modified script here for visibility:

# floating_point.py
import signac

from decimal import Decimal
p = 9

# this produces a weird floating point number
#sp = {'eps': 0.25+p*0.01}

# this produces the correct state point (0.34)
sp = {'eps': float(Decimal(0.25)+p*Decimal(0.01))}

project = signac.get_project()

job = project.open_job(sp)
job.init()
csadorf commented 6 years ago

Original comment by Carl Simon Adorf (Bitbucket: csadorf, GitHub: csadorf).


Instead of providing a programatic solution, we will amend the documentation with best practices concerning the storage of decimal numbers inside JSON-serialized containers.

mikemhenry commented 5 years ago

Just to clarify, the plan is to add some documentation about using python's decimal class for this use case. Any ideas on where would be a good place for it? Poking around, nothing seemed obvious, it doesn't quite fit into a FAQ and it seems to small to be its own topic guide.

csadorf commented 5 years ago

We could add a recipe and add links to it wherever we introduce the statepoint and document.