Skip to content

test: make ValueTest/objects float check robust against x87 excess precision#1700

Open
plusky wants to merge 1 commit into
open-source-parsers:masterfrom
plusky:i586-float-precision-test
Open

test: make ValueTest/objects float check robust against x87 excess precision#1700
plusky wants to merge 1 commit into
open-source-parsers:masterfrom
plusky:i586-float-precision-test

Conversation

@plusky

@plusky plusky commented Jun 25, 2026

Copy link
Copy Markdown

On 32-bit x86 (i586/i686) where GCC defaults to x87 math (-mfpmath=387, 80-bit excess precision) and the baseline has no SSE2, ValueTest/objects fails:

src/test_lib_json/main.cpp(355): 0.12345f == *numericFound
  Expected: 0.12345000356435776
  Actual  : 0.12345

The test stores the float literal 0.12345f into a Json::Value (widened to the stored double) and then asserts equality against the original 0.12345f. On x87 the stored value round-trips to the exact double 0.12345 instead of the float-widened 0.12345000356435776, so the exact double comparison fails — even though the library is correct.

This makes the check precision-robust by comparing the stored value narrowed back to float via asFloat(): both sides collapse to the same float on every architecture, so the numeric round-trip is still verified but the test no longer depends on x87 vs IEEE double representation.

Found while building jsoncpp 1.9.8 for openSUSE on the i586 architecture (no SSE2 in the baseline, so -mfpmath=sse is not an option).

…ecision

ValueTest/objects stores the float literal 0.12345f into a Json::Value
(widened to the stored double) and then asserts equality against the
original 0.12345f. On 32-bit x86 targets where GCC defaults to x87 math
(-mfpmath=387, 80-bit excess precision) and the baseline lacks SSE2, the
round-trip yields the exact double 0.12345 rather than the float-widened
0.12345000356435776, so the exact double comparison fails even though the
library itself is correct.

Compare the stored value narrowed back to float via asFloat(): both the
expected literal and asFloat() collapse to the same float value on every
architecture, keeping the numeric round-trip check while making it
precision-robust.
plusky added a commit to plusky/openSUSE-packaging-skill that referenced this pull request Jun 25, 2026
Document the i586-only exact-float-compare test failure pattern: x87 80-bit
excess precision; -fexcess-precision=standard is a no-op; -mfpmath=sse/-msse2
is unsafe (no SSE2 in the i586 baseline -> SIGILL); fix by narrowing both
sides to float (asFloat()/cast); and verify via the server-side i586 build
(not flaky local QEMU) before the Factory SR. Real case: jsoncpp 1.9.8
ValueTest/objects, upstream PR gh#open-source-parsers/jsoncpp#1700.
bmwiedemann pushed a commit to bmwiedemann/openSUSE that referenced this pull request Jun 27, 2026
https://build.opensuse.org/request/show/1361767
by user pluskalm + dimstar_suse
jsoncpp 1.9.8: fix the i586 FTBFS (declined sr#1361562). ValueTest/objects did an exact float-vs-double compare that x87 80-bit excess precision broke on i586 (no SSE2 in the baseline, so -mfpmath=sse is unsafe). jsoncpp-i586-float-precision.patch compares the value narrowed back to float, robust on all arches; verified i586 build now succeeds (unittest OK, Fail: 0). Submitted upstream as gh#open-source-parsers/jsoncpp#1700.
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.

1 participant