Project

General

Profile

Bug #9596

Possible regression with Wt Dbo floating-point precision (Postgres backend)

Added by Bruce Toll 11 months ago. Updated 2 months ago.

Status:
InProgress
Priority:
Normal
Target version:
Start date:
01/10/2022
Due date:
% Done:

0%

Estimated time:

Description

It appears that there may be a small loss of precision with some floating-point values retrieved from Postgres when using Wt Dbo 4.6.1, compared with 4.5.1.

The attached file 0001-Add-regression-tests-for-floating-point-retrieval.patch adds two tests that illustrate the issue.

Applying the above patch to Wt 4.6.1 and running test.postgres results in 12 errors in my environment (gcc 11.2.0, boost 1.74.0, postgres 12.9):

$ ./test.postgres -l message -t '*/dbo_test48,dbo_test49' -e stdout 2>/dev/null
Running 2 test cases...
DboTest.C(3422): error: in "dbo_test48": check in_value.as_float == out_value.as_float has failed [3.35419397e-37 != 3.35419419e-37]
DboTest.C(3422): error: in "dbo_test48": check in_value.as_float == out_value.as_float has failed [0.000100000005 != 0.000100000012]
DboTest.C(3422): error: in "dbo_test48": check in_value.as_float == out_value.as_float has failed [0.000106811516 != 0.000106811523]
DboTest.C(3422): error: in "dbo_test48": check in_value.as_float == out_value.as_float has failed [0.98999995 != 0.98999989]
DboTest.C(3422): error: in "dbo_test48": check in_value.as_float == out_value.as_float has failed [2.71828175 != 2.71828151]
DboTest.C(3464): error: in "dbo_test49": check in_value.as_double == out_value.as_double has failed [9.9999999999999991e-05 != 0.0001]
DboTest.C(3464): error: in "dbo_test49": check in_value.as_double == out_value.as_double has failed [0.99999999999999989 != 1]
DboTest.C(3464): error: in "dbo_test49": check in_value.as_double == out_value.as_double has failed [1.0000000000000007 != 1.0000000000000009]
DboTest.C(3464): error: in "dbo_test49": check in_value.as_double == out_value.as_double has failed [1000.0000000000001 != 1000]
DboTest.C(3464): error: in "dbo_test49": check in_value.as_double == out_value.as_double has failed [99999999.999999985 != 100000000]
DboTest.C(3464): error: in "dbo_test49": check in_value.as_double == out_value.as_double has failed [9.9999999999999987e+17 != 1e+18]
DboTest.C(3464): error: in "dbo_test49": check in_value.as_double == out_value.as_double has failed [1.0000000000000001e+18 != 1e+18]

NOTE: File paths and test names shortened for clarity.

These errors may be due to commit 81ec366f that replaced std::stof and std::stod with a parser based on Boost Spirit. There is an upstream issue with the Boost Spirit library that seems related and is still unresolved: https://github.com/boostorg/spirit/issues/668.

Repeating the test with test.sqlite3, no errors are reported.

Also, restoring the 4.5.1 version of src/Wt/Dbo/backend/Postgres.C (with all other source files from 4.6.1) and repeating the tests, both test.postgres and test.sqlite3 completed without error. However, the subnormal tests in dbo_test45 failed due to the omission of the subnormal fix in commit 81ec366f (added after 4.5.1, see issue #9490).

For your review, I have attached a patch that attempts to address the precision regression, while retaining the subnormal fix. The patch restores the 4.5.1 stof/stod implementation while adding exception handling to retry std::out_of_range errors with the Boost Spirit code (to handle subnormals). I haven't checked how much overhead this exception handling adds, but the updated code passes the subnormal tests (dbo_test45), as well as the new floating-point retrieval tests (dbo_test48 and dbo_test49).

See related: #9595. If I can provide any additional information, please let me know.


Files

Also available in: Atom PDF