Why does modular division (%) only work with integers?

Recently, I came across a question that could be easily solved using modular division, but the input was float:

For a periodic function (for example, sin ) and a computer function that can only calculate it over a range of periods (for example, [-π, π]), create 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 is this not working? I get this error:

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

Interestingly, it works in Python:

 def sin(x): return limited_sin((x + math.pi) % (2 * math.pi) - math.pi) 
+73
c ++ c
May 23 '11 at 20:57
source share
9 answers

Since the normal mathematical concept of "remainder" applies only to integer division. that is, the division that is required to generate an integer quotient.

To expand the concept of "remainder" to real numbers, you need to introduce a new kind of "hybrid" operation that will generate an integer quotient for real operands. Core C does not support such an operation, but is provided as a standard fmod library, as well as remainder on C99. (Note that these functions do not match and have some features. In particular, they do not follow the rules for rounding integer division.)

+72
May 23 '11 at 21:06
source share

You are looking for fmod () .

I think it is more specific to answer your question, in older languages ​​the % operator was simply defined as integer modular division, and in newer languages ​​he decided to expand the definition of the operator.

EDIT: If I was sure why, I would say because the idea of ​​modular arithmetic comes from number theory and deals specifically with integers.

+47
May 23 '11 at 21:00
source share

I can’t say for sure, but I assume that it is mostly historical. Quite a few early C compilers did not support floating point at all. It was added later, and even then not so completely - basically a data type was added, and the most primitive operations were supported in this language, but everything else remained in the standard library.

+15
May 23 '11 at 21:08
source share

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

+12
May 23 '11 at 21:00
source share

Limitations in standards:

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

Each of the operands must have an arithmetic type. The operands of the% operator must be of integer type.

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

The operands * and / must be of arithmetic or enumerated type; % operands must have an integer or enumeration type. Normal arithmetic conversions are performed on operands and determine the type of result.

The solution is to use fmod , which is why the % operands are primarily limited to an integer type, in accordance with Justification C99 § 6.5.5 Multiplicative operators:

The C89 committee rejected the proposal to use the% operator to work with floating types, since such use would duplicate the facility provided by fmod

+7
Jul 10 '13 at 0:56
source share

try fmod

+4
May 23 '11 at 21:00
source share

The% operator gives you a REMAINDER (another name for the module) number. For C / C ++, this is defined only for entire operations. Python is a little wider and allows you to get the rest of the floating point number for the rest of the number of times this number:

 >>> 4 % math.pi 0.85840734641020688 >>> 4 - math.pi 0.85840734641020688 >>> 
+2
May 23 '11 at 21:05
source share

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

Therefore, you can try using the fmod function from math.h / cmath.h or use these lines of code to avoid using this 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 )); 

}

+2
Oct 28 '14 at 13:53 on
source share

"The mathematical concept of arithmetic modulo also works for floating point values, and this is one of the first problems that Donald Knuth discusses in his classic book, The Art of Computer Programming (Volume I). That is, once it was basic knowledge."

The floating point module operator is defined as follows:

 m = num - iquot*den ; where iquot = int( num/den ) 

As indicated, the non-operator of the% operator for floating point numbers seems to be related to standards. CRTL provides "fmod" and, as a rule, the "remainder" to execute% on fp numbers. The difference between the two is how they deal with the intermediate rounding of the quota ’.

'remainder' uses rounding to the nearest, and 'fmod' uses simple truncation.

If you write your own C ++ numeric classes, nothing prevents you from changing the legacy without an operation, including the overloaded% operator.

respectfully

0
Feb 08 '19 at 8:14
source share



All Articles