我需要计算带小数的模数,也可以是负数 例如:fmod(-5.2,3); 虽然mod()适用于整数,而fmod()(或fmodf())适用于小数,但fmod()返回带有小数位数的错误结果:
前:
double modulo = fmod (5.2, 3);
NSLog (@"==> %f", modulo);
==> 2.2 // This is correct !!
double modulo = fmod (-5.2, 3);
NSLog (@"==> %f", modulo);
==> -2.2 // This is wrong !! should be 0.8
库中是否有另一个mod()或我应该编写自己的十进制负mod函数? 类似的东西:
if (res = fmod(x,m) < 0) {
res+=m;
}
Thx!
答案 0 :(得分:4)
-2.2是正确的,也是-5.2 mod 3. fmod
函数是C函数(因此也是Objective C),因此您可以通过键入man fmod
来查找有关它的更多详细信息。终奌站。在执行fmod
时,它将保留您正在修改的值的符号。因此,要获得所需的mod,您需要检查符号(结果或传入的值),如果是负数,则需要添加模数基数,在本例中为3。
这是fmod函数的定义:
double
fmod(double x, double y);
Specifically, the functions return the value x-i*y, for some integer i such that, if y is non-zero, the result has the same sign as x and magnitude less than the magnitude of y.
来自OS X手册页。
答案 1 :(得分:2)
出于您的目的,您可以执行以下操作:
#include <math.h>
float f_mod(float a, float n) {
return a - n * floor(a / n);
}
当然,请务必核对n>0
。
f_mod(-5.2f, 2.0f) = 0.8
f_mod(5.2f, 2.0f) = 2.2
答案 2 :(得分:0)
谢谢你,所以我最终写了一个包装...我跳的是什么,我可以避免。这对我很有用,在我看来,它代表了模数的正确数学定义(不是C实现)。我确信这个功能可以优化,但为了清楚起见我这样做:
//--
//-- Modulo
//--
double calcModulo ( double x, double m) {
double res = INFINITY;
if (m==0)
return res ;
double posMod, negMod, posM, posX;
posM = m < 0 ? -m:m;
posX = x < 0 ? -x:x;
posMod = fmod (posX, posM);
negMod = fmod (-posX,posM) + posM;
// pick up the correct res
if ( x >= 0 ){
if (m > 0) {
res = posMod;
} else {
res = -negMod;
}
}else{
if (m > 0) {
res= negMod;
} else{
res= -posMod;
}
}
return res;
}