相关疑难解决方法(0)

+0.0和-0.0上的哪些操作和功能会产生不同的算术结果?

在C中,当±0.0支持-0.0+0.0分配给a时double通常不会产生算术差异.尽管它们具有不同的位模式,但它们在算术上比较相同.

double zp = +0.0;
double zn = -0.0;
printf("0 == memcmp %d\n", 0 == memcmp(&zn, &zp, sizeof zp));// --> 0 == memcmp 0
printf("==          %d\n", zn == zp);                        // --> ==          1
Run Code Online (Sandbox Code Playgroud)

受到@Pascal Cuoq评论的启发,我正在寻找标准C中的一些功能,这些功能提供了算术上不同的结果.

注意:许多功能,如sin(),返回+0.0f(+0.0)-0.0f(-0.0).但这些并不能提供不同的算术结果.这两个结果也不应该同时存在NaN.

c floating-point

20
推荐指数
2
解决办法
1003
查看次数

对于复数乘法,g ++与手动优化

在我们的代码库中,我们有很多操作,如j*ω*X,其中j是虚数单位,ω是实数,X是复数.实际上很多循环看起来像:

#include <complex>
#include <vector>

void mult_jomega(std::vector<std::complex<double> > &vec, double omega){
    std::complex<double> jomega(0.0, omega);
    for (auto &x : vec){
        x*=jomega;
    }
}
Run Code Online (Sandbox Code Playgroud)

但是,我们利用了真实部分jomega为零的事实并将乘法写为:

void mult_jomega_smart(cvector &vec, double omega){
    for (auto &x : vec){
        x={-omega*x.imag(), omega*x.real()};
    }
}
Run Code Online (Sandbox Code Playgroud)

一开始,我对这种"聪明"的转变不屑一顾,因为

  1. 它更难理解.
  2. 错误的概率更高.
  3. "无论如何,编译器都会优化它".

然而,正如一些表现回归所显示的那样,第三个论点并不成立.当比较这两种功能(见下文列表),智能版采用一贯优于-O2以及具有-O3:

size    orig(musec)   smart(musec)  speedup
10      0.039928      0.0117551     3.39665
100     0.328564      0.0861379     3.81439
500     1.62269       0.417475      3.8869
1000    3.33012       0.760515      4.37877
2000    6.46696       1.56048       4.14422
10000   32.2827       9.2361        3.49528
100000  326.828       115.158       2.8381 …
Run Code Online (Sandbox Code Playgroud)

c++ optimization gcc clang

9
推荐指数
1
解决办法
604
查看次数

标签 统计

c ×1

c++ ×1

clang ×1

floating-point ×1

gcc ×1

optimization ×1