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)
Because the normal mathematical notion of "remainder" is only applicable to integer division. i.e. division that is required to generate integer quotient.
In order to extend the concept of "remainder" to real numbers you have to introduce a new kind of "hybrid" operation that would generate integer quotient for real operands. Core C language does not support such operation, but it is provided as a standard library fmod function, as well as remainder function in C99. (Note that these functions are not the same and have some peculiarities. In particular, they do not follow the rounding rules of integer division.)
You're looking for fmod().
I guess to more specifically answer your question, in older languages the % operator was just defined as integer modular division and in newer languages they decided to expand the definition of the operator.
EDIT: If I were to wager a guess why, I would say it's because the idea of modular arithmetic originates in number theory and deals specifically with integers.
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.
The modulo operator % in C and C++ is defined for two integers, however, there is an fmod() function available for usage with doubles.
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
try fmod
"The mathematical notion of modulo arithmetic works for floating point
values as well, and this is one of the first issues that Donald Knuth
discusses in his classic The Art of Computer Programming (volume I).
I.e. it was once basic knowledge."
The floating point modulus operator is defined as follows:
m = num - iquot*den ; where iquot = int( num/den )
As indicated, the no-op of the % operator on floating point numbers appears
to be standards related. The CRTL provides 'fmod', and usually 'remainder'
as well, to perform % on fp numbers. The difference between these two lies
in how they handle the intermediate 'iquot' rounding.
'remainder' uses round-to-nearest, and 'fmod' uses simple truncate.
If you write your own C++ numerical classes, nothing prevents you
from amending the no-op legacy, by including an overloaded operator %.
Best Regards
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));
}
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
>>>
Related
K&R's C language has the following sentence:
A compiler's license to treat mathematically associative operators as computationally associative is revoked.
This is in the Appendix C, which tells what's different from before ANSI C. But I don't know how computationally associated is different from mathematically associated. Maybe I guess the mathematically associative is a * b * c = (a * b) * c (left), or a * (b * c) (right).
Consider this code:
#include <stdio.h>
int main(void)
{
double a = 0x1p64; // Two the power of 64, 18,446,744,073,709,551,616.
double b = 1;
double c = -a;
printf("%g\n", a+b+c);
}
In the C grammar, a+b+c is equivalent to (a+b)+c, so a and b are added first, and then c is added. In the format commonly used for double, a+b yields 264, not 264+1, because the double format does not have enough precision to represent 264+1, so the result of the addition is the ideal mathematical result rounded to the nearest representable value, which is 264. Then adding c yields zero, so “0” is printed.
If instead we calculated a+c+b, adding a and c would give zero, and then adding b would give one, and “1” would be printed.
Thus, floating-point operations are not generally associative; a+b+c is not the same as a+c+b.
In ordinary mathematics with real numbers, a+b+c is the same as a+c+b; addition of real numbers is associative.
Prior to standardization, some C compilers would treat floating-point expressions as if operators were associative (for those operators whose counterparts in real-number-arithmetic were associative). The C standard does not permit that in implementations that conform to the standard. Conforming compilers must produce results as if the operations were performed in the order specified by the C grammar.
Some compilers may still treat floating-point operators as associative when operating in non-standard modes, which may be selected by flags or switches passed to the compiler. Also, because the C standard allows implementations to perform floating-point arithmetic with more precision than the nominal type (e.g., when computing a+b+c, it can calculate it as if the types were long double instead of double), that can produce results that are the same as if operations were rearranged, so you can still get results that look like operators have been reordered associatively, depending on the C implementation and the flags used.
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)
Because the normal mathematical notion of "remainder" is only applicable to integer division. i.e. division that is required to generate integer quotient.
In order to extend the concept of "remainder" to real numbers you have to introduce a new kind of "hybrid" operation that would generate integer quotient for real operands. Core C language does not support such operation, but it is provided as a standard library fmod function, as well as remainder function in C99. (Note that these functions are not the same and have some peculiarities. In particular, they do not follow the rounding rules of integer division.)
You're looking for fmod().
I guess to more specifically answer your question, in older languages the % operator was just defined as integer modular division and in newer languages they decided to expand the definition of the operator.
EDIT: If I were to wager a guess why, I would say it's because the idea of modular arithmetic originates in number theory and deals specifically with integers.
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.
The modulo operator % in C and C++ is defined for two integers, however, there is an fmod() function available for usage with doubles.
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
try fmod
"The mathematical notion of modulo arithmetic works for floating point
values as well, and this is one of the first issues that Donald Knuth
discusses in his classic The Art of Computer Programming (volume I).
I.e. it was once basic knowledge."
The floating point modulus operator is defined as follows:
m = num - iquot*den ; where iquot = int( num/den )
As indicated, the no-op of the % operator on floating point numbers appears
to be standards related. The CRTL provides 'fmod', and usually 'remainder'
as well, to perform % on fp numbers. The difference between these two lies
in how they handle the intermediate 'iquot' rounding.
'remainder' uses round-to-nearest, and 'fmod' uses simple truncate.
If you write your own C++ numerical classes, nothing prevents you
from amending the no-op legacy, by including an overloaded operator %.
Best Regards
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));
}
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
>>>
I took a quiz in my CS class today and got a question about the modulo operator wrong because I didn't know about the availability of % in C, I've been using fmod(). Why do both exist? Is one better/faster or do they just deal with different data types?
modulo division using % operator in C only works for integer operands and returns an integer remainder of the division.
The function fmod accepts double as arguments meaning that it accepts non-integer values and returns the remainder of the division.
Additional note on fmod: how is the remainder calculated in case of double operand? Thanks #chux for showing the documentation on how fmod calculates the remainder of a floating point division.
The floating-point remainder of the division operation x/y calculated
by this function is exactly the value x - n*y, where n is x/y with its
fractional part truncated.
The returned value has the same sign as x and is less or equal to y in
magnitude.
On the other hand, when the modulo division binary operator (%) was first designed, it was determined by the language designers that it would only support operands of 'integer' types because technically speaking, the notion of 'remainder' in mathematics only applies to integer divisions.
It's because % is an integer operator, and fmod stands for floatmod and is used for floating point numbers.
Why do both exist?
Because they may have computed different results, even with the same values. These differences may occur with negative values. In essence fmod() and % were different mathematical functions.
fmod(x,y), since C89, had the result "the result has the same sign as x and magnitude less than the magnitude of y".
i%j was not so singularly defined. See Remainder calculation for the modulo operation. This allow code to use existing variant processors effectively. The div() function was created to address this variability. Ref
By C99 they compute the same for the same values. Future C could allow 123.4 % 56.7
% is just integer modulo
fmod is float modulo and can be used as described in MSDN.
https://msdn.microsoft.com/en-us/library/20dckbeh.aspx
#include <stdio.h>
int main()
{
char c;
c=10;
if(c%2==0)
printf("Yes");
return 0;
}
The above code prints "Yes". Can someone tell why the modulus operator works for char and int but not for double etc.?
You already got comments explaining why % is defined for char: it's defined for all integer types, and in C, char is an integer type. Some other languages do define a distinct char type that does not support arithmetic operations, but C is not one of them.
But to answer why it isn't defined for floating-point types: history. There is no technical reason why it wouldn't be possible to define the % operator for floating-point types. Here's what the C99 rationale says:
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 (see §7.12.10.1).
And as mafso found later:
7.12.10.1 The fmod functions
[...]
The C89 Committee considered a proposal to use the remainder operator % for this function; but it was rejected because the operators in general correspond to hardware facilities, and fmod is not supported in hardware on most machines.
They seem somewhat contradictory. The % operator was not extended because fmod already filled that need, but fmod was picked to fill that need because the committee did not want to extend the % operator? They cannot very well both be true at the same time.
I suspect one of these reasons was the original reason, and the other was the reason for not later re-visiting that decision, but there's no telling which was first. Either way, it was simply decided that % wouldn't perform this operation.
#include<stdio.h>
void main()
{
float a = 5, b = 2;
int c;
c = a % b;
printf("%d", c);
}
I am getting floating point error n this program-me..
someone please explain this..
You can only use % operator with integer operands. Use fmod function (declared in math.h) for floating point operands.
The operands of the operator % have to be integral (i.e. int, byte, ...). You will have to cast the floats first:
c = ((int)a) % ((int) b);
The concept of "remainder" is only applicable to integer division. i.e. division that required to generate integer quotient.
In older languages the % operator was just defined as integer modular division. Quite a few early C compilers didn't support floating point at all. It was added on later, and most primitive operations supported in the language, but everything else left to the standard library.
For floating point numbers, a new operation is required that would generate integer quotient for floating point operands.
Core C language does not support such operation, but it is provided as a standard library fmod function, as well as remainder function in C99.