相关疑难解决方法(0)

如何在C/C++/Obj-C中编写处理负数的模数(%)运算符

我厌恶的C语言(作为一名数学家)就是这样的

(-1) % 8 // comes out as -1, and not 7

fmodf(-1,8) // fails similarly
Run Code Online (Sandbox Code Playgroud)

什么是最好的解决方案?

C++允许模板和运算符重载的可能性,但这些对我来说都是模糊的.感激地收到了例子.

c c++ operator-overloading modulo c++11

81
推荐指数
5
解决办法
23万
查看次数

三向比较运算符与减法有何不同?

<=>在C++ 20中有一个新的比较运算符.但是我认为在大多数情况下,简单的减法效果很好:

int my_strcmp(const char *a, const char *b) {
    while (*a == *b && *a != 0 && *b != 0) {
        a++, b++;
    }
    // Version 1
    return *a - *b;
    // Version 2
    return *a <=> *b;
    // Version 3
    return ((*a > *b) - (*a < *b));
}
Run Code Online (Sandbox Code Playgroud)

它们具有相同的效果.我无法理解其中的差异.

c++ comparison-operators spaceship-operator c++20

51
推荐指数
3
解决办法
7480
查看次数

+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
查看次数

将0,负和正映射到0,1,2的无分支代码

写一个无分支函数,如果两个有符号整数之间的差为零,负或正,则返回0,1或2.

这是一个分支版本:

int Compare(int x, int y)
{
    int diff = x - y;
    if (diff == 0)
        return 0;
    else if (diff < 0)
        return 1;
    else
        return 2;
}
Run Code Online (Sandbox Code Playgroud)

这是一个可能更快的版本,具体取决于编译器和处理器:

int Compare(int x, int y)
{
    int diff = x - y;
    return diff == 0 ? 0 : (diff < 0 ? 1 : 2);
}
Run Code Online (Sandbox Code Playgroud)

你能想出一个没有分支的更快的吗?

摘要

我基准测试的10个解决方案具有相似的性能.实际数字和获胜者取决于编译器(icc/gcc),编译器选项(例如,-O3,-march = nocona,-fast,-xHost)和机器. 佳能的解决方案在许多基准测试中表现良好,但性能优势再次轻微.令我感到惊讶的是,在某些情况下,某些解决方案比使用分支的天真解决方案慢.

c++ optimization bit-manipulation

14
推荐指数
5
解决办法
4751
查看次数

C中整数的快速符号

C中有一个符号函数:

int sign(int x)
{
    if(x > 0) return 1;
    if(x < 0) return -1;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

不幸的是,比较成本非常高,所以我需要修改功能以减少比较次数.

我尝试了以下方法:

int sign(int x)
{
    int result;
    result = (-1)*(((unsigned int)x)>>31);

    if (x > 0) return 1;

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

在这种情况下,我只得到一个比较.

有什么方法可以避免比较吗?

编辑 可能重复没有给出一个问题的答案,因为所有的答案是C++,使用比较(我应该避免的)或不返回-1,+1,0.

c

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

何时/为什么(a <0)可能在表达式中分支?

在阅读了关于这个问题的许多评论之后,有几个人(这里这里)建议这段代码:

int val = 5;
int r = (0 < val) - (val < 0); // this line here
Run Code Online (Sandbox Code Playgroud)

会引起分支.不幸的是,他们都没有给出任何理由或者说它为什么会导致分支(三角形暗示它需要类似cmove指令或预测,但并不真正说明原因).

这些人是否正确"表达中使用的比较不会产生分支"实际上是神话而不是事实?(假设你没有使用一些深奥的处理器)如果是这样,你能举个例子吗?

我以为不会有任何分支(假设没有逻辑"短路"),现在我很好奇.

c++

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

一次计算正弦和余弦

我有一个使用相同参数的正弦和余弦的科学代码(我基本上需要该参数的复数指数).我想知道是否有可能比分别调用正弦和余弦函数更快.

另外我只需要0.1%的精度.那么有什么方法可以找到默认的触发功能并截断功率系列的速度?

我想到的另一件事是,有没有办法执行余数运算,结果总是积极的?在我自己使用的算法中,x=fmod(x,2*pi);但如果x为负数,我需要加2pi(较小的域意味着我可以使用较短的幂级数)

编辑:LUT原来是最好的方法,但我很高兴我了解了其他近似技术.我还建议使用明确的中点近似.这就是我最终做的事情:

const int N = 10000;//about 3e-4 error for 1000//3e-5 for 10 000//3e-6 for 100 000
double *cs = new double[N];
double *sn = new double[N];
for(int i  =0;i<N;i++){
    double A= (i+0.5)*2*pi/N;
    cs[i]=cos(A);
    sn[i]=sin(A);
}
Run Code Online (Sandbox Code Playgroud)

以下部分近似(中点)sincos(2*pi*(wc2 + t [j]*(cotp*t [j] -wc)))

double A=(wc2+t[j]*(cotp*t[j]-wc));
int B =(int)N*(A-floor(A));
re += cs[B]*f[j];
im += sn[B]*f[j];
Run Code Online (Sandbox Code Playgroud)

另一种方法可能是使用切比雪夫分解.您可以使用orthogonality属性来查找系数.针对指数进行了优化,它看起来像这样:

double fastsin(double x){
    x=x-floor(x/2/pi)*2*pi-pi;//this line can be improved, both inside this 
                              //function and before you input it into the function

    double x2 …
Run Code Online (Sandbox Code Playgroud)

c++ algorithm trigonometry

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

有负股息的分部,但向负无穷大四舍五入?

请考虑以下代码(在C++ 11中):

int a = -11, b = 3;
int c = a / b;
// now c == -3
Run Code Online (Sandbox Code Playgroud)

C++ 11规范称负股息的除法向零舍入.

对于有一个运算符或函数来进行除向负无穷大的舍入非常有用(例如,为了在迭代范围时与正红利保持一致),那么标准库中是否有一个函数或运算符可以满足我的需要?或者也许是在现代编译器中执行它的编译器定义的函数/内在函数?

我可以编写自己的,例如以下(仅适用于正数除数):

int div_neg(int dividend, int divisor){
    if(dividend >= 0) return dividend / divisor;
    else return (dividend - divisor + 1) / divisor;
}
Run Code Online (Sandbox Code Playgroud)

但它不会像我的意图那样描述,也可能不是标准库函数或编译器内在优化(如果存在).

c++ division c++11

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

基于C++中另一个数组的成员对数组进行排序

我的问题是下一个(这是一个显示问题的简单示例):

我有:

int* array1;
double* array2. 

array1=new int[10];
array2=new double[10];
array1=filledWithIntegers(random);
array2=filledWithDoubles(random);
Run Code Online (Sandbox Code Playgroud)

//这里我想基于array2值对array1进行排序.我正在尝试使用stdlib的qsort函数.qsort(array1,6,sizeof(int),compare);

关键是如何基于array2为order1生成比较函数.

不可能使用std库数据结构,它必须直接在数组指针中完成.

谢谢.

c++ arrays sorting qsort

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

Qsort和Comparators奇怪的行为.C

所以,我在C库的C程序中使用qsort.它按预期工作,所以我决定玩比较器.

比较器1(我用它):

 int compare (const void * a, const void * b)
{
  if (*(double*)a > *(double*)b) return 1;
  else if (*(double*)a < *(double*)b) return -1;
  else return 0;  
}
Run Code Online (Sandbox Code Playgroud)

比较器2:

int comp (const void *a, const void *b)
{
    const double *ia = (const double *)a; // casting pointer types 
    const double *ib = (const double *)b;
    return *ia  - *ib; 
}
Run Code Online (Sandbox Code Playgroud)

第一个按我想要的方式工作.第二个应该是第一个做同样的事情.我想使用第二个,因为程序运行得快一点,但事实上它并没有真正排序任何东西!

我很确定我在较小的阵列上使用了比较器#2并且它有效.除非我在那里遗漏了什么.

c sorting algorithm pointers

4
推荐指数
1
解决办法
81
查看次数