microsoft / microsoft/STL

<complex>: Many functions produce incorrect results for complex NaNs and infinities

Open
#887 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug
Dominant language
C++
Stars
11.2k
Forks
1.7k
Avg merge
4d 15h
Merged PRs (30d)
22

Description

Describe the bug
Many functions in <complex> don't produce the correct result for complex NaNs and infinities as specified in C Annex G.

Command-line test case
This is not a comprehensive list of incorrect behavior. There are tests (which currently fail) in libcxx for the requirements.

G:\Temp>type complex4.cpp
#include <cmath>
#include <complex>
#include <iostream>
#include <limits>
using namespace std;

template <typename T>
void print_result(const char* expr, const T& expected, const T& actual) {
    cout << expr << "\n"
         << "  Expected: " << expected << "\n"
         << "    Actual: " << actual << "\n"
         << "\n";
}

#define EVAL_AND_PRINT(expr, expected) print_result(#expr, expected, expr)

constexpr double operator""_pi(long double x) { return static_cast<double>(x) * 3.1415926535897932; }

constexpr double operator""_pi(unsigned long long x) { return static_cast<double>(x) * 3.1415926535897932; }

int main() {
    constexpr double inf = numeric_limits<double>::infinity();
    constexpr double nan = numeric_limits<double>::quiet_NaN();

    EVAL_AND_PRINT(complex(inf, nan) * complex(1.0, 0.0), complex(inf, nan));
    EVAL_AND_PRINT(complex(inf, nan) / complex(1.0, 0.0), complex(inf, nan));
    EVAL_AND_PRINT(sinh(complex(inf, nan)), complex(inf, nan));
    EVAL_AND_PRINT(cosh(complex(0.0, inf)), complex(nan, 0.0));
    EVAL_AND_PRINT(tanh(complex(inf, nan)), complex(1.0, 0.0));
    EVAL_AND_PRINT(acos(complex(0.0, nan)), complex(0.5_pi, nan));
    EVAL_AND_PRINT(atanh(complex(inf, nan)), complex(0.0, nan));
    EVAL_AND_PRINT(exp(complex(inf, inf)), complex(inf, nan));
}

G:\Temp>cl /EHsc /std:c++17 /W4 /WX .\complex4.cpp
用于 x64 的 Microsoft (R) C/C++ 优化编译器 19.26.28806 版
版权所有(C) Microsoft Corporation。保留所有权利。

complex4.cpp
Microsoft (R) Incremental Linker Version 14.26.28806.0
Copyright (C) Microsoft Corporation.  All rights reserved.

/out:complex4.exe
complex4.obj

G:\Temp>.\complex4.exe
complex(inf, nan) * complex(1.0, 0.0)
  Expected: (inf,nan)
    Actual: (nan,-nan(ind))

complex(inf, nan) / complex(1.0, 0.0)
  Expected: (inf,nan)
    Actual: (nan,nan)

sinh(complex(inf, nan))
  Expected: (inf,nan)
    Actual: (inf,inf)

cosh(complex(0.0, inf))
  Expected: (nan,0)
    Actual: (-nan(ind),-nan(ind))

tanh(complex(inf, nan))
  Expected: (1,0)
    Actual: (nan,nan)

acos(complex(0.0, nan))
  Expected: (1.5708,nan)
    Actual: (nan,nan)

atanh(complex(inf, nan))
  Expected: (0,nan)
    Actual: (nan,nan)

exp(complex(inf, inf))
  Expected: (inf,nan)
    Actual: (inf,inf)

STL version

Microsoft Visual Studio Community 2019
版本 16.6.1

Additional context
Should we bypass the checks and/or use faster but less stable algorithms when CX_LIMITED_RANGE, /fp:fast or -ffast-math is on? (especially for the "cheap" operations like operator* and norm)

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the supplied complex4.cpp reproducer and the libcxx tests mentioned in the issue, then inspect the implementation and its handling of NaNs and infinities. Done means the affected functions produce the C Annex G results covered by those tests, including the listed operations.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
tooling
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.