Division by complex in clang++ versus g++

前端 未结 4 1685
无人及你
无人及你 2021-02-19 16:57

When I compile the following code with g++ (4.8.1 or 4.9.0) or clang++ (3.4) I get different outputs.

#include 
#include 

int mai         


        
4条回答
  •  暗喜
    暗喜 (楼主)
    2021-02-19 17:46

    Ok so I have this wild guess, that in clang the complex number division is implemented like described on wiki: http://en.wikipedia.org/wiki/Complex_number#Multiplication_and_division.

    One can see that the denominator is in the form c^2 + d^2. So 1.e-162 squared actually falls out of the IEE754 representable range for double which is std::numeric_limits::min() - 2.22507e-308, and we have an underflow.

    gcc somehow works this out, but if clang does simple square, as per @40two's standard quotation it enters into UB, and treats it as 0 after performing 1.e-162^2 + 0.0^2.

    I tested clang and gcc for a number that should not result with underflow when squared.

    #include 
    #include 
    
    int main() {
      std::complex c = {1.e-104,0};
      std::cout << 1.0/c << std::endl;
      return 0;
    }
    

    Results are fine:

    luk32:~/projects/tests$ g++ --std=c++11 ./complex_div.cpp 
    luk32:~/projects/tests$ ./a.out 
    (1e+104,0)
    luk32:~/projects/tests$ clang++ --std=c++11 ./complex_div.cpp 
    luk32:~/projects/tests$ ./a.out 
    (1e+104,0)
    

    Not sure if this is a bug. But I think this is what is going on.

    Addendum:

    (inf,-nan) is also consistent if one evaluates those expressions by hand

    We get:

    real = (ac+bd) / (o)  - real part 
    imag = (bc-ad) / (o)  - imaginary part
    
    {a,b} = {1.0, 0.0}
    {c,d} = {1.e-104, 0.0}
    
    o is (c^2 + d^2) and we assume it is 0.0.
    
    real / o = (1.e-104 * 1.0 + 0.0 * 0.0) / o = 1/o = inf
    imag / o = (0.0 * 1.e-104 - 1.0 * 0.0) / o = -0.0 / o = -nan
    

    I am just not absolutetly sure about the sign of -0.0 and -nan, I don't know IEE754 enough to evaluate (0.0 * 1.e-104 - 1.0 * 0.0). But everything seems consistent.

提交回复
热议问题