Skip to content

<complex>: pow, incorrect type conversion #1260

@fsb4000

Description

@fsb4000

Describe the bug
wrong results with pow

Command-line test case

C:\Temp>type repro.cpp
#include <complex>
#include <type_traits>
#include <cassert>

template <typename T>
double promote(T, typename std::enable_if<std::is_integral<T>::value>::type* = 0);

float promote(float);
double promote(double);
long double promote(long double);

#pragma warning(disable:4244)
template <typename T,  typename U>
void test(const std::complex<T>& x, U y)
{
    typedef decltype(promote(std::real(x))+promote(y)) V;
    static_assert((std::is_same<decltype(std::pow(x, y)), std::complex<V> >::value), "");
    
    assert(std::pow(x, y) == std::pow(std::complex<V>(x), std::complex<V>(y, 0)));
    // (std::pow(x, y) - std::pow(std::complex<V>(x), std::complex<V>(y, 0)) == (1.7053e-12,-4.54747e-13)
    // if we cast y to V then it works:
    //assert(std::pow(x, static_cast<V>(y)) == std::pow(std::complex<V>(x), std::complex<V>(y, 0)));
}

int main()
{
    const auto cf = std::complex(3.0f, 4.0f);
    const auto cd = std::complex(3.0, 4.0);
    const auto cld = std::complex(3.0L, 4.0L);

    test(cf, 5);
    test(cd, 5);
    test(cld, 5);

    test(cf, 5u);
    test(cd, 5u);
    test(cld, 5u);

    test(cf, 5LL);
    test(cd, 5LL);
    test(cld, 5LL);
}

C:\Temp>cl /W4 /WX  /EHsc /std:c++latest repro.cpp
Оптимизирующий компилятор Microsoft (R) C/C++ версии 19.28.29213 для x64
(C) Корпорация Майкрософт (Microsoft Corporation).  Все права защищены.

/std:c++latest предоставляется как предварительная версия языковых функций из последнего
рабочего черновика C++. Мы приветствуем сообщения об ошибках и предложения к улучшению.
Однако обратите внимание, что эти функции предоставляются как есть, без поддержки и могут
измениться или быть удалены по мере развития рабочего черновика. Дополнительные сведения:
https://go.microsoft.com/fwlink/?linkid=2045807.

repro.cpp
Microsoft (R) Incremental Linker Version 14.28.29213.0
Copyright (C) Microsoft Corporation.  All rights reserved.

/out:repro.exe
repro.obj

C:\Temp>repro
Assertion failed: std::pow(x, y) == std::pow(std::complex<V>(x), std::complex<V>(y, 0)), file repro.cpp, line 19

Expected behavior
Tests should pass

STL version
Microsoft Visual Studio Community 2019 Preview Version 16.8.0 Preview 2.0

Additional context
Skipped libcxx test

# STL bug: Incorrect return types.
std/numerics/complex.number/cmplx.over/pow.pass.cpp FAIL

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingfixedSomething works now, yay!

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions