Why does modulus division (%) only work with integ

2018-12-31 16:59发布

I recently ran into an issue that could easily be solved using modulus division, but the input was a float:

Given a periodic function (e.g. sin) and a computer function that can only compute it within the period range (e.g. [-π, π]), make a function that can handle any input.

The "obvious" solution is something like:

#include <cmath>

float sin(float x){
    return limited_sin((x + M_PI) % (2 *M_PI) - M_PI);
}

Why doesn't this work? I get this error:

error: invalid operands of types double and double to binary operator %

Interestingly, it does work in Python:

def sin(x):
    return limited_sin((x + math.pi) % (2 * math.pi) - math.pi)

标签: c++ c
8条回答
孤独寂梦人
2楼-- · 2018-12-31 17:05

try fmod

查看更多
还给你的自由
3楼-- · 2018-12-31 17:06

I can't really say for sure, but I'd guess it's mostly historical. Quite a few early C compilers didn't support floating point at all. It was added on later, and even then not as completely -- mostly the data type was added, and the most primitive operations supported in the language, but everything else left to the standard library.

查看更多
与君花间醉酒
4楼-- · 2018-12-31 17:16

The % operator gives you a REMAINDER(another name for modulus) of a number. For C/C++, this is only defined for integer operations. Python is a little broader and allows you to get the remainder of a floating point number for the remainder of how many times number can be divided into it:

>>> 4 % math.pi
0.85840734641020688
>>> 4 - math.pi
0.85840734641020688
>>> 
查看更多
裙下三千臣
5楼-- · 2018-12-31 17:26

The % operator does not work in C++, when you are trying to find the remainder of two numbers which are both of the type Float or Double.

Hence you could try using the fmod function from math.h / cmath.h or you could use these lines of code to avoid using that header file:

float sin(float x) {
 float temp;
 temp = (x + M_PI) / ((2 *M_PI) - M_PI);
 return limited_sin((x + M_PI) - ((2 *M_PI) - M_PI) * temp ));

}

查看更多
千与千寻千般痛.
6楼-- · 2018-12-31 17:27

The modulo operator % in C and C++ is defined for two integers, however, there is an fmod() function available for usage with doubles.

查看更多
还给你的自由
7楼-- · 2018-12-31 17:30

The constraints are in the standards:

C11(ISO/IEC 9899:201x) §6.5.5 Multiplicative operators

Each of the operands shall have arithmetic type. The operands of the % operator shall have integer type.

C++11(ISO/IEC 14882:2011) §5.6 Multiplicative operators

The operands of * and / shall have arithmetic or enumeration type; the operands of % shall have integral or enumeration type. The usual arithmetic conversions are performed on the operands and determine the type of the result.

The solution is to use fmod, which is exactly why the operands of % are limited to integer type in the first place, according to C99 Rationale §6.5.5 Multiplicative operators:

The C89 Committee rejected extending the % operator to work on floating types as such usage would duplicate the facility provided by fmod

查看更多
登录 后发表回答