c++中的模函数,其行为类似于matlab中的mod

Modulo function in c++, that behaves like mod in matlab

本文关键字:类似于 matlab 中的 mod 函数 c++      更新时间:2023-10-16

我对周期域(框)中的许多粒子(最多100000个)进行了模拟,为了让粒子留在框内,我使用了带有浮点或双数的模函数。

Matlab中,使用mod功能一切都很好。然而,在C++中,我发现函数fmod并不完全等于Matlab的mod函数:

mod(-0.5,10)=9.5-我想在C++ 中得到这个结果

fmod(-0.5,10)=-0.5-我不想要这个。

I、 当然,可以用if语句解决我的问题。然而,我认为,这将影响效率(如果语句在关键循环中)。有没有一种方法可以在没有if语句的情况下实现这个函数?可能是其他功能?

谢谢。

只需使用一个条件。它不会对效率产生有意义的影响。

inline double realmod (x, y)
{
  result = fmod(x, y);
  return result >= 0 ? result : result + y;
}

CCD_ 10调用汇编指令CCD_,http://www.intel.com/design/pentium/manuals/24143004.pdf)。条件和浮点加法的跳转指令只有5个左右

当你的代码有浮点除法时,你不需要为小事而烦恼。

使用floor和正则除法:

float modulo(float a, float q)
{
    float b = a / q;
    return (b - floor(b)) * q;
}

或者可以将除数添加到fmod的结果中,而不需要分支:

float modulo(float a, float q)
{
    float m = fmod(a, q);
    return m + q * (m < 0.f);
}    

基于Matlabmod(a, m)文档和@QuestionC的答案-

一个与Matlab行为完全相同的通用解决方案-也适用于负和零除数。

针对多个值进行测试:

static inline double MatlabMod(double q, double m)
{
  if(m == 0)
    return q;
  double result = fmod(q, m);
  return ((result >= 0 && m > 0) || (q <= 0 && m < 0)) ? result : (result + m);
}

用matlab测试:

(q, m) -> result

(54321)->54

(-50512)->462

(54,-152)->-98

(-53,-500)->-53

(-500300)->100

(-5000040)->200

(-1000,-360)->-280

(500360)->140

(1000360)->280

(-1000360)->80

(-5051,0)->-5051

(512,0)->512

(0,52)->0

(0,-58)->0

在应用模运算符之前,只需将除数添加到要在区间中保留的数字即可:

return fmod(a+q,q);

这根本不需要分支。

如果你必须担心a在两次更新之间超过-q,你可以通过以下方式使其更加健壮:

return fmod(a+q*10,q);

适用于CCD_ 18

最简单的方法是在没有任何分支的情况下同时处理浮点和int。

// b = MOD(a, m)
int a = a - m * floor(a / m) + m; 
int b = a - m * floor(a / m);