Skip to content

<cmath>: Special Math ellint_2() produces wrong result when angle is close to 2 * pi #6152

@StephanTLavavej

Description

@StephanTLavavej

Originally reported as DevCom-10383094 / internal VSO-1830422.

We wrap Boost.Math (currently 1.90) so this unsurprisingly repros with upstream Boost. The results don't vary between MSVC Compiler 19.51 and Clang 20.1.8:

C:\Temp>type meow.cpp
#if defined(USE_BOOST)
#include <boost/math/special_functions/ellint_2.hpp>
using boost::math::ellint_2;
#elif defined(USE_STD)
#include <cmath>
using std::ellint_2;
#else
static_assert(false, "Define either USE_BOOST or USE_STD.");
#endif

#include <iostream>
using std::cout;

int main() {
#if defined(USE_BOOST)
    cout << "Using boost.\n";
#else
    cout << "Using std.\n";
#endif
    const double v1 = ellint_2(0.1, 6.283);
    cout << "ellint_2(0.1, 6.283) = " << v1 << "\n";
    const double v2 = ellint_2(0.1, 6.283185307179586);
    cout << "ellint_2(0.1, 6.283185307179586) = " << v2 << "\n";
    const double v3 = ellint_2(0.5, 6.283185307179586);
    cout << "ellint_2(0.5, 6.283185307179586) = " << v3 << "\n";
}
C:\Temp>cl /EHsc /nologo /W4 /std:c++latest /MTd /Od /I D:\GitHub\STL\boost-math\include /DUSE_BOOST meow.cpp && meow
meow.cpp
Using boost.
ellint_2(0.1, 6.283) = 6.26726
ellint_2(0.1, 6.283185307179586) = -nan(ind)
ellint_2(0.5, 6.283185307179586) = -nan(ind)

C:\Temp>cl /EHsc /nologo /W4 /std:c++latest /MTd /Od /DUSE_STD meow.cpp && meow
meow.cpp
Using std.
ellint_2(0.1, 6.283) = 6.26726
ellint_2(0.1, 6.283185307179586) = -nan(ind)
ellint_2(0.5, 6.283185307179586) = -nan(ind)

C:\Temp>clang-cl /EHsc /nologo /W4 /std:c++latest /MTd /Od /I D:\GitHub\STL\boost-math\include /DUSE_BOOST meow.cpp && meow
Using boost.
ellint_2(0.1, 6.283) = 6.26726
ellint_2(0.1, 6.283185307179586) = -nan(ind)
ellint_2(0.5, 6.283185307179586) = -nan(ind)

C:\Temp>clang-cl /EHsc /nologo /W4 /std:c++latest /MTd /Od /DUSE_STD meow.cpp && meow
Using std.
ellint_2(0.1, 6.283) = 6.26726
ellint_2(0.1, 6.283185307179586) = -nan(ind)
ellint_2(0.5, 6.283185307179586) = -nan(ind)

Compiler Explorer comparison

What I find extremely curious is that Boost 1.90 with GCC, Boost 1.90 with Clang, and GCC/libstdc++'s Special Math (Clang/libc++ is currently missing Special Math) behave differently. In particular, Boost 1.90 with Clang exhibits different behavior on Windows versus Linux (Clang 20 vs. Clang 22 makes no difference). This suggests to me that Boost.Math is using CRT functions that behave differently between the Windows UCRT and Linux glibc:

https://godbolt.org/z/4jvMGsvqW

Using std.
ellint_2(0.1, 6.283) = 6.26726
ellint_2(0.1, 6.283185307179586) = 6.26745
ellint_2(0.5, 6.283185307179586) = 5.86985

Using boost.
ellint_2(0.1, 6.283) = 6.26726
ellint_2(0.1, 6.283185307179586) = 6.26745
ellint_2(0.5, 6.283185307179586) = 5.86985

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingexternalThis issue is unrelated to the STL

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions