Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TFormula: Possibility of failure during dynamic compilation of predefined functions "gausn" and "landau" #17225

Open
1 task
AlexeyVKrasnoperov opened this issue Dec 9, 2024 · 0 comments · May be fixed by #17327
Assignees
Labels

Comments

@AlexeyVKrasnoperov
Copy link

Check duplicate issues.

  • Checked for duplicates

Description

It may happen that the program has a locale with a comma as a decimal separator
("fr_FR.utf8", "de_DE.utf8", "ru_RU.utf8", .. ).
In this case, initialization of the TFormula objects with functions "gausn" and "landau"
ends with an error. The following messages are displayed on the screen:
...
input_line_11:2:158: error: too many arguments to function call, expected single argument 'x', have 2 arguments
Double_t TFormula____id3053186198674332598(Double_t *x,Double_t *p){ return p[0]*TMath::Exp(-0.5*(((x[0])-p[1])/p[2])*(((x[0])-p[1])/p[2]))/(TMath::Sqrt(2*3,141593)*p[2]) ; }
...

input_line_13:2:115: error: too many arguments to function call, expected at most 4, have 5
Double_t TFormula____id3986067622224738083(Double_t *x,Double_t *p){ return p[0]*TMath::Landau((x[0]),p[1],p[2],0,000000) ; }
...

Reproducer

It is enough to execute this macro in ROOT with different locale names as a parameter.

#include <TFormula.h>
#include <locale.h>

void CheckTFormula(const char *locale = nullptr)
{  
  if( locale != nullptr )
    {
      const char * ptr = setlocale(LC_NUMERIC,locale);
      if( ptr == nullptr )
        {
          fprintf(stderr,"Cannot set locale: \"%s\"\n",locale);
          return;
        }
      printf("Numeric locale: \"%s\"\n",ptr);
    }
  lconv * lc = localeconv();
  if( lc != nullptr )
    printf("Decimal point: \"%s\"\n",lc->decimal_point);
  //
  double num = 12345.67890;
  printf("printf: \"%lf\"\n",num);  
  printf("TString::Format: \"%s\"\n\n",TString::Format("%lf",num).Data());
  //
  TFormula f0("f0","gausn(x)");
  if( f0.IsValid() )
    {
      f0.Print();
      printf("\n");
    }
  //
  TFormula f1("f1","landau(x)");
  if( f1.IsValid() )
    f1.Print();
}

ROOT version

ROOT 6.32.08. Perhaps everywhere, starting from new TFromula ?

Installation method

build from source

Operating system

Linux, Debian 12.8

Additional context

To prevent the appearance of additional arguments and set the correct constants,
it is enough to forcibly replace the comma with a dot when converting floating-point numbers to strings.

In file: root/hist/hist/src/TFormula.cxx
https://github.com/root-project/root/blob/2c8521e17d40134df0e6194b993387fcade96d97/hist/hist/src/TFormula.cxx#L2266
The code on the line 2266
TString value = TString::Format("%lf", (*constIt).second);
need to be replaced with
TString value = TString::Format("%lf", (*constIt).second).ReplaceAll(",",".");

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
Status: No status
Development

Successfully merging a pull request may close this issue.

2 participants