Can't Mod Zero?
The C++ Standard(2003) says in §5.6/4,
[...] If the second operand of / or % is zero the behavior is undefined; [...]
That is, following expressions invoke undefined-behavior(UB):
X / 0; //UB
X % 0; //UB
Note also that -5 % 2
is NOT equal to -(5 % 2)
(as Petar seems to suggest in his comment to his answer). It's implementation-defined. The spec says (§5.6/4),
[...] If both operands are nonnegative then the remainder is nonnegative; if not, the sign of the remainder is implementation-defined.
Why is 0 mod 0 an error?
In mathematics, x mod 0
is undefined, hence the error.
I am new to C and having trouble with using modulus
Using the modulus operator gives you the remainder after it divides the left-hand operand by right-hand operand. Your loop starts at iter = 0, and you do:
mod = number%iter;
Which does division by zero. To use the modulus operator means doing a division, and checking the remainder. On my compiler at least it specifies what the exception is.
Unhandled exception at -------- Integer division by zero
Division by zero is undefined not only in programming, but in maths too. You can't divide by zero. The comedian Steven Wright said "Black holes are where God divided by zero." So adjust your code accordingly.
Understanding The Modulus Operator %
(This explanation is only for positive numbers since it depends on the language otherwise)
Definition
The Modulus is the remainder of the euclidean division of one number by another. %
is called the modulo operation.
For instance, 9
divided by 4
equals 2
but it remains 1
. Here, 9 / 4 = 2
and 9 % 4 = 1
.
In your example: 5 divided by 7 gives 0 but it remains 5 (5 % 7 == 5
).
Calculation
The modulo operation can be calculated using this equation:
a % b = a - floor(a / b) * b
floor(a / b)
represents the number of times you can dividea
byb
floor(a / b) * b
is the amount that was successfully shared entirely- The total (
a
) minus what was shared equals the remainder of the division
Applied to the last example, this gives:
5 % 7 = 5 - floor(5 / 7) * 7 = 5
Modular Arithmetic
That said, your intuition was that it could be -2 and not 5. Actually, in modular arithmetic, -2 = 5 (mod 7)
because it exists k in Z such that 7k - 2 = 5
.
You may not have learned modular arithmetic, but you have probably used angles and know that -90° is the same as 270° because it is modulo 360. It's similar, it wraps! So take a circle, and say that its perimeter is 7. Then you read where is 5. And if you try with 10, it should be at 3 because 10 % 7
is 3.
Why does a%b produce SIGFPE when b is zero?
The operation triggers SIGFPE:
SIG is a common prefix for signal
names; FPE is an acronym for
floating-point exception. Although
SIGFPE does not necessarily involve
floating-point arithmetic, there is no
way to change its name without
breaking backward compatibility.
GDB is a bit clearer about this and calls it "Arithmetic exception":
(gdb) run
Starting program: /home/emil/float
Program received signal SIGFPE, Arithmetic exception.
0x0804837d in main () at float.c:4
4 int c=a%b;
Can't use modulus on doubles?
The %
operator is for integers. You're looking for the fmod()
function.
#include <cmath>
int main()
{
double x = 6.3;
double y = 2.0;
double z = std::fmod(x,y);
}
Mod Closest to Zero
Code is optimal or at least nearly so. Some platforms may work better with some variation.
There is not a single C integer operator that handles this.
The challenges to this is the problem is that the range of results is [-180:180]
and this is 361 different values. It is unclear if it is allowed to have func(180)
return -180
.
The next challenge is to have code work over the entire [INT_MIN...INT_MAX]
range as angle + 180
can overflow. angle %= 360;
takes care of that.
Following is a effectively a variation of OP's code which may run faster on pipe-lined machines. It only does one %
operation - conceivably the most expensive. Positive angle
returns [-179:180] and negative angle
returns [-180:179]
int func2(int angle) {
angle %= 360;
return angle + 360*((angle < -180) - (angle > 180));
}
Following is a one-liner that returns values [-180:179]. It does not use angle + 180
as that may overflow.
int func3(int angle) {
return ((angle % 360) + (360+180))%360 - 180;
}
There is the <math.h>
function double remainder(double x, double y);
that closely meets OP's goal. (Maybe available since C99.) It will return FP values [-180:180]. Note: int
could have an integer range that exceeds what double
can represent exactly.
int func4(int angle) {
angle = remainder(angle, 360.0);
return angle;
}
Why does modulus division (%) only work with integers?
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.)
Related Topics
Rotate an Image Without Cropping in Opencv in C++
How to Get the Md5 Hash of a File in C++
C++ Get Name of Type in Template
How to Compile For Os X in Linux or Windows
C++ Alignment When Printing Cout ≪≪
How to Implement Matlab'S Mldivide (A.K.A. the Backslash Operator "\")
Enable C++11 in Eclipse Cdt (Juno/Kepler/Luna) Indexer
Floating Point Keys in Std:Map
Undefined Reference to Boost::System::System_Category() When Compiling
Sending and Receiving 2D Array Over Mpi
Will New Return Null in Any Case
How to Convert a String Variable Containing Time to Time_T Type in C++
C++11 Aggregate Initialization For Classes With Non-Static Member Initializers