https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68397
Bug ID: 68397 Summary: std::tr1::expint fails in __expint_En_cont_frac for some long double arguments due to low __max_iter value Product: gcc Version: unknown Status: UNCONFIRMED Severity: trivial Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: uquendo at gmail dot com Target Milestone: --- Created attachment 36746 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=36746&action=edit patch increasing __max_iter in __expint_En_cont_frac @ libstdc++-v3/include/tr1/exp_integral.tcc Continued fractions for the exponential integral E_n(x) fail to converge in std::tr1::expintl ( std::tr1::expint(long double) ) for some long double arguments in the interval [1.0;1.4] due to low std::numeric_limits<long double>::epsilon(). Raising in [gcc.git]/libstdc++-v3/include/tr1/exp_integral.tcc __max_iter value in __expint_En_series(unsigned int __n, _Tp __x) function from 100 to 1000 resolves the issue, patch is attached. minimal test for reproducing this bug follows: __________________________________________________ #include <iostream> #include <stdexcept> #include <tr1/cmath> int main(int argc, char* argv[]){ std::cout.precision(10); for(long double x=-1.600001L; x<-0.9L; x+=0.05L){ try{ std::cout << "std::tr1::expint(" << x << ")= " << std::tr1::expint(x) << std::endl; } catch (std::exception& e){ std::cerr << "std::tr1::expint(" << x << ") failed with error: " << e.what() << std::endl; } } return 0; } __________________________________________________ compiling with g++ -O0 test.cpp and running, i've got: std::tr1::expint(-1.600001)= -0.08630820751 std::tr1::expint(-1.550001)= -0.09288197123 std::tr1::expint(-1.500001)= -0.1000194337 std::tr1::expint(-1.45) failed with error: Continued fraction failed in __expint_En_cont_frac. std::tr1::expint(-1.4) failed with error: Continued fraction failed in __expint_En_cont_frac. std::tr1::expint(-1.35) failed with error: Continued fraction failed in __expint_En_cont_frac. std::tr1::expint(-1.3) failed with error: Continued fraction failed in __expint_En_cont_frac. std::tr1::expint(-1.25) failed with error: Continued fraction failed in __expint_En_cont_frac. std::tr1::expint(-1.2) failed with error: Continued fraction failed in __expint_En_cont_frac. std::tr1::expint(-1.15) failed with error: Continued fraction failed in __expint_En_cont_frac. std::tr1::expint(-1.1) failed with error: Continued fraction failed in __expint_En_cont_frac. std::tr1::expint(-1.05) failed with error: Continued fraction failed in __expint_En_cont_frac. std::tr1::expint(-1) failed with error: Continued fraction failed in __expint_En_cont_frac. std::tr1::expint(-0.950001)= -0.2387371166 std::tr1::expint(-0.900001)= -0.2601834876 after changing argument to double or raising __max_iter as mentioned above, i've been able to obtain expected results: std::tr1::expint(-1.600001)= -0.08630820751 std::tr1::expint(-1.550001)= -0.09288197123 std::tr1::expint(-1.500001)= -0.1000194337 std::tr1::expint(-1.450001)= -0.1077772781 std::tr1::expint(-1.400001)= -0.1162191364 std::tr1::expint(-1.350001)= -0.1254166524 std::tr1::expint(-1.300001)= -0.1354507482 std::tr1::expint(-1.250001)= -0.1464131433 std::tr1::expint(-1.200001)= -0.1584081859 std::tr1::expint(-1.150001)= -0.1715550783 std::tr1::expint(-1.100001)= -0.1859906019 std::tr1::expint(-1.050001)= -0.2018724799 std::tr1::expint(-1.000001)= -0.2193835665 std::tr1::expint(-0.950001)= -0.2387371166 std::tr1::expint(-0.900001)= -0.2601834876