相关疑难解决方法(0)

转换为int vs floor

这些之间有什么区别:

float foo1 = (int)(bar / 3.0);
float foo2 = floor(bar / 3.0);
Run Code Online (Sandbox Code Playgroud)

据我所知,两种情况都有相同的结果.编译代码有什么区别吗?

c c++ floating-point

108
推荐指数
3
解决办法
7万
查看次数

如何在SSE/AVX中使用融合乘法 - 加法(FMA)指令

我已经了解到一些Intel/AMD CPU可以同时进行多次复用并添加SSE/AVX:
每个周期的FLOPS用于沙桥和haswell SSE2/AVX/AVX2.

我想知道如何在代码中做到最好,我也想知道它是如何在CPU内部完成的.我的意思是超标量架构.假设我想做一个很长的总和,如下面的SSE:

//sum = a1*b1 + a2*b2 + a3*b3 +... where a is a scalar and b is a SIMD vector (e.g. from matrix multiplication)
sum = _mm_set1_ps(0.0f);
a1  = _mm_set1_ps(a[0]); 
b1  = _mm_load_ps(&b[0]);
sum = _mm_add_ps(sum, _mm_mul_ps(a1, b1));

a2  = _mm_set1_ps(a[1]); 
b2  = _mm_load_ps(&b[4]);
sum = _mm_add_ps(sum, _mm_mul_ps(a2, b2));

a3  = _mm_set1_ps(a[2]); 
b3  = _mm_load_ps(&b[8]);
sum = _mm_add_ps(sum, _mm_mul_ps(a3, b3));
...
Run Code Online (Sandbox Code Playgroud)

我的问题是如何将其转换为同时乘法并添加?数据可以依赖吗?我的意思是CPU可以_mm_add_ps(sum, _mm_mul_ps(a1, b1))同时执行还是在乘法中使用的寄存器和add必须是独立的?

最后,这如何适用于FMA(与Haswell)?是_mm_add_ps(sum, _mm_mul_ps(a1, b1))自动转换为单个FMA指令还是微操作?

c sse cpu-architecture avx fma

40
推荐指数
2
解决办法
3万
查看次数

Excel如何成功地舍入浮点数,即使它们不精确?

例如,这篇博客说0.005并不完全是0.005,但是舍入这个数字会产生正确的结果.

我在C++中尝试了各种舍入,但在将数字舍入到某些小数位时失败了.例如,Round(x,y)将x舍入为y的倍数.所以回合(37.785,0.01)应该给你37.79而不是37.78.

我正在重新打开这个问题,向社区寻求帮助.问题在于浮点数的不精确性(37,785表示为37.78499999999).

问题是Excel如何解决这个问题?

对于上述问题,在C++中浮点数的轮()中的解决方案是不正确的.

c++ math floating-point excel rounding

22
推荐指数
2
解决办法
4511
查看次数

g ++优化选项影响sin函数的值

我对libc的"sin"功能有疑问.

#include <cmath>
#include <stdio.h>

int main(int argc, char **argv)
{
    double tt = 6.28318530717958620000; // 2 * M_PI
    double yy = ::sin(tt);

    printf("%.32f\n", yy);

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

当使用"g ++"编译上述代码而没有任何优化选项时,它将输出"-0.00000000000000024492127076447545".但如果使用"-O3"选项,则输出"-0.00000000000000024492935982947064".

为什么不在没有"-O3"的情况下返回"-0.00000000000000024492935982947064"?提前致谢.

c c++

12
推荐指数
1
解决办法
621
查看次数

-O1更改浮点数学

c++当使用-O0或编译时,以下程序给出的数值不同-O1

#include <iostream>
#include <array>
#include <cmath>
#include <iomanip>

int main()
{
  std::array<double, 2> v;
  v.fill(0);

  std::get<0>(v) = 0x1.5b4d3afe1f7d2p-1;
  double theta = 0x1.1aef12f82caf9p+2;

  double c = std::cos(theta);
  double s = std::sin(theta);
  double vi = c * std::get<0>(v) - s * std::get<1>(v);
  double vj = s * std::get<0>(v) + c * std::get<1>(v);
  std::get<0>(v) = vi;
  std::get<1>(v) = vj;

  std::cout << std::hexfloat;
  for (const auto& x : v)
    std::cout << x << " ";
  std::cout << std::endl; …
Run Code Online (Sandbox Code Playgroud)

c++ floating-point gcc

12
推荐指数
1
解决办法
229
查看次数

GNU C++中程序的奇怪行为,使用浮点数

看看这个程序:

#include <iostream>
#include <cmath>

using namespace std;

typedef pair<int, int> coords;

double dist(coords a, coords b)
{
    return sqrt((a.first - b.first) * (a.first - b.first) +
              (a.second - b.second) * (a.second - b.second));
}

int main()
{
    coords A = make_pair(1, 0);
    coords B = make_pair(0, 1);
    coords C = make_pair(-1, 0);
    coords D = make_pair(0, -1);

    cerr.precision(20);
    cerr << dist(A, B) + dist(C, D) << endl;
    cerr << dist(A, D) + dist(B, C) << endl;

    if(dist(A, B) + …
Run Code Online (Sandbox Code Playgroud)

c++ floating-point double gcc compiler-optimization

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

我可以保证C++编译器不会重新排序我的计算吗?

我目前正在阅读优秀的双双和四双算术库,在前几行我注意到他们通过以下方式执行求和:

std::pair<double, double> TwoSum(double a, double b)
{
    double s = a + b;
    double v = s - a;
    double e = (a - (s - v)) + (b - v);
    return std::make_pair(s, e);
}
Run Code Online (Sandbox Code Playgroud)

误差的计算e依赖于计算遵循该操作顺序的事实,因为IEEE-754浮点数学的非关联属性.

如果我在现代优化C++编译器(例如MSVC或gcc)中编译它,我可以确保编译器不会优化计算的方式吗?

其次,这在C++标准中是否可以保证?

c++ floating-point optimization ieee-754

7
推荐指数
3
解决办法
4101
查看次数

平方根总和的比较

我有MinGW GCC 4.8.1和以下代码:

#include <iostream>
#include <cmath>

double eval(int a, int b){
    return std::sqrt(a) + std::sqrt(b);
}

int main(){
    double first = eval(545, 331);
    double second = eval(545, 331);

    if(first < second)
        std::cout << "first <  second" << std::endl;
    if(first == second)
        std::cout << "first == second" << std::endl;
    if(first > second)
        std::cout << "first >  second" << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

如果编译-O0,程序打印预期的结果:

first == second
Run Code Online (Sandbox Code Playgroud)

但是,如果使用-O1,-O2或编译-O3程序打印:(结果在ideone上)

first <  second
first == …
Run Code Online (Sandbox Code Playgroud)

c++ sqrt

6
推荐指数
1
解决办法
244
查看次数

pow() 在特定条件下返回错误结果(以及意外修复) - 为什么会这样?

我一直在创建一个用于实施 Eratosthenes 筛分的简短程序。在他的程序中,我使用 int startingPointwhich 保存了当前素数的值,它的乘法被标记为非素数,从它的平方开始。我使用 pow() 函数计算当前循环中起点的平方。这样做的时候,我遇到了一个奇怪的现象。当startingPoint等于 时5,则后int i = pow(startingPoint,2)的值为i24,而不是 25。这种现象仅在startingPoint等于 5时发生。之后,我运行了一些测试,导致以下代码片段:

#include <iostream>
#include <math.h>

int main()
{
    int p=5;

    int num1 = pow(5,2);
    int num2 = pow(p,2);
    float num3 = pow(p,2);
    int num4 = floor(pow(p,2));

    std::cout.precision(10);

    std::cout<<num1<<std::endl; //25
    std::cout<<num2<<std::endl; //24
    std::cout<<std::fixed<<num3<<std::endl; //25.0000000000
    std::cout<<num4<<std::endl; //25            
}
Run Code Online (Sandbox Code Playgroud)

可以看出,如果我powint文字调用,结果将是数字的实际平方。但是,如果我使用 using 调用它int p=5,那么pow返回的结果实际上比预期的结果低一个。如果我将结果传递给一个float变量,它也会收到正确的结果。

现在,我知道pow计算幂的方法是通过近似计算,因此,在转换为整数时可能会出现诸如此类的错误。我可能就让它这样吧。但真正让我停下来思考的是num4. pow(p,2) …

c++ gcc pow

6
推荐指数
0
解决办法
1942
查看次数

为什么打印变量会改变它的值?

我有一个小函数,它应该根据机器学习算法进行预测.该函数无法正常工作,因此我将一个print语句放入检查值,突然间它开始工作了.当我注释掉打印行时,它会再次停止工作.有什么我不知道为什么会发生这种情况?

int makePrediction( const InstanceT & instance, bool biased ){
  double dotProduct = ( biased ? instance * _weights + _bias : instance * _weights ); 
  std::cout << "dotProduct = " << dotProduct << std::endl;
  return ( dotProduct > 0 ? 1 : -1 );
}
Run Code Online (Sandbox Code Playgroud)

由于某种原因产生了不同的结果

int makePrediction( const InstanceT & instance, bool biased ){
  double dotProduct = ( biased ? instance * _weights + _bias : instance * _weights ); 
  return ( dotProduct > 0 ? 1 : …
Run Code Online (Sandbox Code Playgroud)

c++ printing cout stdout

5
推荐指数
1
解决办法
980
查看次数

是否存在算术运算受编译器优化影响的情况?

这是一个普遍的问题,但由于我主要处理gcc/g ++/VStudio,我将其标记为c/c ++.当我搞乱优化选项时,我想到了这个问题.在最简单的形式中,考虑算术运算,如i / 6 * 8.如果一个人面对这个表达,他很可能将它简化为类似的东西i / 3 * 4.如果他更习惯乘以4,他将首先这样做,即(i * 4) / 3.我必须再次强调,这只是一个简单的例子.

那么编译器呢?他们是否有可能对此类操作采取相同措施?而且既然我们知道在上面的例子中,如果i是一个整数,那么简化和改变操作的顺序可能会导致完全不同的结果,问题可以改为:编译器是否完全避免了这样的动作?

如果我们希望程序完全按照我们的说法进行一些算术运算而不改变运算顺序,那么我们是否应该担心编译器的行为?

c c++ compilation compiler-optimization

3
推荐指数
2
解决办法
180
查看次数