Data grid adding decimal places to a rounded figure

Hi,

I’ve created a calculator app that stores values in a database and displays them in a DataGrid
but I’m running into an issue where some figures that are saved as rounded figures to 2 decimal places within a database table are displaying in the DataGrid with more decimals places than they have in the database table itself. For example a figure may be saved within the database as 941.82 but display in the DataGrid as 941.8200000000001. Does anyone know what might be going wrong? Screenshots of an example are below.

I’m not comfortable sharing the app publicly but happy to share privately with an admin etc.

Thanks

This link might be helpful

Thank you Tony. I’ll have a look. I’m still not sure why it should display with additional decimal points considering that it is stored in the database with only 2 decimal places. The repeating panel items code I used was:
self.liquid_slag_rpt.items = app_tables.liquid_slag_results.search(User=user)

Surely it should just display all amounts as they are stored in the database?

Is the database column type “Number”?

Hi p.colbert, yeah the database column type is number. Is that not advisable?

It’s perfectly fine. It does mean, however, that numbers with a fractional part are stored using the Python float type, which does not have any specific number of fractional digits. The fractional point “floats” as needed, hence the name.

Furthermore, float is not decimal. It is binary. So the only fractions that are exact are negative powers of two (0.5, 0.25, 0.125, etc.) or whole-number multiples thereof. Everything else is as close as the format allows, which means that it is very slightly off from the input value, in the database, and everywhere else.

This effect is not limited to Python. Python is using an industry-standard binary number format. This format is actually supported at the hardware level, for speed, on most modern equipment. Numbers in this format are stored in binary, for maximum precision, and converted back to decimal for display. (And converted from decimal, for computation and storage.)

Where the converted decimal number ends in all trailing zeroes, and in the absence of more specific instructions, Python typically “cleans up” the result by omitting the trailing zeroes. (You will see this when someone enters a value ending in .50; which will display as “.5”, not “.50”.)

But once in a while, that tiny discrepancy at the very tail end rounds the final decimal digit up or down, so the trailing digits are not quite all zeroes.

What happens to the occasional “offending” digit is up to the specific program. Some programs will compensate for it one way, others another, and others not at all. You’re seeing just that kind of disagreement here. Data Tables are compensating, while the Data Grid components are not.

For your own display, you know that the numbers are good to exactly two decimal places, no more. In that case, you should probably ask your Python code to display specifically to that many places, and no more than that.

1 Like

Thank you for taking the time to explain p.colbert. That’s a very thorough explanation and it makes sense now.

I struggled with this when I first started but found the easiest solution to use a label in the row template with a data binding that is rounded. This way it doesn’t matter what data the label gets, it will always be displayed correctly.

1 Like

The data binding should format rather than round, otherwise you risk to end up on the same problem.

Rounding a float 0.82 to the second digit will give you the same binary representation which is close enough but not exactly 0.82 and will leak that tail of digits when converted to string.

Creating the string representation of the same number can be done specifying the number of digits and it’s safer: f'{value:.2f}' will always round to and show two digits.

4 Likes