Skip to content

Conversation

guitargeek
Copy link
Contributor

Closes #17797 by making string conversion to double and printing of doubles to strings independent of locale settings.

@guitargeek guitargeek self-assigned this Aug 24, 2025
@guitargeek guitargeek requested a review from lmoneta as a code owner August 24, 2025 13:45
@guitargeek guitargeek force-pushed the issue-17797 branch 2 times, most recently from c4f3f2b to 7195dcc Compare August 24, 2025 16:38
Copy link

github-actions bot commented Aug 24, 2025

Test Results

    21 files      21 suites   3d 13h 7m 43s ⏱️
 3 618 tests  3 477 ✅  0 💤 141 ❌
74 193 runs  74 035 ✅ 17 💤 141 ❌

For more details on these failures, see this check.

Results for commit d90d12c.

♻️ This comment has been updated with latest results.

When constructing a RooProdPdf, the list of pdfs has to be passed in a
collection. I noticed this problem now by making the conversion of
strings to doubles a bit stricter and throw on failure.

The test only passed by chance before.
Refactor to make the code simpler and skip the debug printouts.

Creating RooRealVars is pretty straight forward, so I don't think it's
worth to do logging here.

One has to pay the price for string manipulations and flooding the debug
log that will not help users to understand problems.
The conversions from strings to double should be locale-independent,
otherwise one might silently get wrong results when the locale is set to
e.g. german, where they use a comma instead of a period for floating
point numbers.

Closes root-project#17797.
This ensures that RooFit printouts will be independent of the locale
setting.

Here is my little script to test this:

```Python
import locale

def check_numeric_locale():

    locale.setlocale(locale.LC_ALL, "")

    # Get the active numeric locale
    current = locale.setlocale(locale.LC_NUMERIC)
    print(f"Active LC_NUMERIC: {current}")

    # Format a floating point number according to this locale
    number = 12345.67
    formatted = locale.format_string("%.2f", number, grouping=True)
    print(f"Formatted number: {formatted}")

    # Show what decimal point is being used
    conv = locale.localeconv()
    print(f"Decimal point: {conv['decimal_point']}")
    print(f"Thousands separator: {conv['thousands_sep']}")

if __name__ == "__main__":
    check_numeric_locale()

    import ROOT

    print(ROOT.std.stod("3.33"))

    x = ROOT.RooRealVar("x", "x", 3.12, -10., 10.)
    x.setError(1.23)

    print(x.format(4, ""))

    ROOT.RooRealVar.printScientific(True)

    x.writeToStream(ROOT.std.cout, False)

    x.writeToStream(ROOT.std.cout, True)
```
The `std::to_string` function is not locale-independent, so we should
better not use is for floating point numbers.
Copy link
Member

@dpiparo dpiparo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

@guitargeek
Copy link
Contributor Author

Thanks for the review! I accidentally pushed an unrelated commit to this branch, but I removed that one again to get back to the state of where the PR was reviewed.

@vepadulano vepadulano removed their request for review August 26, 2025 07:54
@guitargeek guitargeek merged commit 4e09bb1 into root-project:master Aug 26, 2025
43 of 51 checks passed
@guitargeek guitargeek deleted the issue-17797 branch August 26, 2025 08:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[RF] RooWorkspace.factory() parse dependence on LC_NUMERIC settings
2 participants