Weird mod behavior in Obj. C - c

I have the following code:
NSInteger index1 = (stop.timeIndex - 1); //This will be -1
index1 = index1 % [stop.schedule count]; // [stop.schedule count] = 33
So I have the expression -1 % 33. This should give me 32, but is instead giving me 3... I've double checked the values in the debugger. Does anyone have any ideas?

In C, the modulus operator doesn't work with negative numbers. (It gives a remainder, rather than doing modular arithmetic as its common name suggests.)

C99 says in Section 6.5.5 Multiplicative operators (bold mine):
The result of the / operator is the quotient from the division of the first operand by the
second; the result of the % operator is the remainder. In both operations, if the value of
the second operand is zero, the behavior is undefined.
When integers are divided, the result of the / operator is the algebraic quotient with any
fractional part discarded. If the quotient a/b is representable, the expression
(a/b)*b + a%b shall equal a.
It says that % is the remainder, and does not use the word "modulus" to describe it. In fact, the word "modulus" only occurs in three places in my copy of C99, and those all relate to the library and not to any operator.
It does not say anything that requires that the remainder be positive. If a positive remainder is required, then rewriting a%b as (a%b + b) % b will work for either sign of a and b and give a positive answer at the expense of an extra addition and division. It may be cheaper to compute it as m=a%b; if (m<0) m+=b; depending on whether missed branches or extra divisions are cheaper in your target architecture.
Edit: I know nothing about Objective-C. Your original question was tagged C and all answers to date reflect the C language, although your example appears to be Objective-C code. I'm assuming that knowing what is true about C is helpful.

The results of using the mod operator on negative numbers are often unexpected. For example, this:
#include <stdio.h>
int main() {
int n = -1 % 33;
printf( "%d\n", n );
}
produces -1 with GCC, but I can't see why you expect the expression to evaluate to 32 - so it goes. It's normally better not to perform such operations, particularly if you want your code to be portable.

Related

Why do both % and fmod() exist in C

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

Is there any possibility of divide-by-zero in this conditional statement?

This is tricking my mind a little bit, because i can't seem to find any problem with this code.
Anyways, here's the riddle:
Suppose someone injects a random value into a, b:
int foo(int a, int b)
{
return b ? (a / b): 0;
}
b != 0 always!
Is it possible for an integer zero division exception to occur?
I'm starting to think this is a prank, yet....
NOTE:
This question was published in a conference, there is a possibility that the author was specific to a compiler/architecture where this is problematic.
No, divide by zero is not possible here.
Quoting C11, chapter §6.5.15, Conditional operator , (emphasis mine)
The first operand is evaluated; there is a sequence point between its evaluation and the
evaluation of the second or third operand (whichever is evaluated). The second operand
is evaluated only if the first compares unequal to 0; the third operand is evaluated only if
the first compares equal to 0; [...]
So, in case, b is 0, the expression (a/b) will not be evaluated.
That said, just as note:
The division is integer division.
If you have a wrapper, that ensures b != 0, then you could cut down the whole function call and simply write someVar = a/b;
Also, I don't know of any architecture which (possibly) changes the aforesaid behavior.
There is no possibility for a division by 0 in your example, yet there is another special case you should check for: dividing INT_MIN by -1 may cause a division overflow, and usually causes an fatal exception on Intel hardware, a surprising behavior, yet consistent with the C Standard that specifies that integer overflow can cause an implementation specific behavior.
If you need to protect against such unwanted behavior, you must special case these operands and handle them specifically:
#include <limits.h>
int foo(int a, int b) {
if (b == 0) return 0;
if (a == INT_MIN && b == -1) return INT_MAX;
return a / b;
}
Since the values of a and b can be crafted by an external source, you definitely need to worry about division overflow. It is a fun game to play to try a crash unsafe calculators by feeding them these values.

Why do you get different values for integer division in C89?

For example, suppose you have these variables:
int i = 9;
int j = 7;
Depending on the implementation, the value of, (-i)/j, could be either –1 or –2. How is it possible to get these two different results?
Surprisingly the result is implementation defined in C89:
ANSI draft § 3.3.5
When integers are divided and the division is inexact, if both
operands are positive the result of the / operator is the largest
integer less than the algebraic quotient and the result of the %
operator is positive. If either operand is negative, whether the
result of the / operator is the largest integer less than the
algebraic quotient or the smallest integer greater than the algebraic
quotient is implementation-defined
However this was changed in C99
N1256
§ 6.5.5/6
When integers are divided, the result of the / operator is the algebraic quotient with any fractional part discarded*
With a footnote:
* This is often called "truncation toward zero"
To clarify, "implementation defined" means the implementation must decide which one, it doesn't mean sometimes you'll get one thing and sometimes you'll get another (unless the implementation defined it to do something really strange like that, I guess).
In C89, the result of division / can be truncated either way for negative operands. (In C99, the result will be truncated toward zero.)
The historical reason is explained in C99 Rationale:
Rationale for International Standard — Programming Languages — C §6.5.5 Multiplicative operators
In C89, division of integers involving negative operands could round upward or downward in an implementation-defined manner; the intent was to avoid incurring overhead in run-time code to check for special cases and enforce specific behavior. In Fortran, however, the result will always truncate toward zero, and the overhead seems to be acceptable to the numeric programming community. Therefore, C99 now requires similar behavior, which should facilitate porting of code from Fortran to C.

Weird results of modulo arithmetic with negative numbers and unsigned denominators

I have an array in C that I want to address in manner similar to a circular buffer, so for example: a[-1] would return me the last element of the array.
To do that I tried to use modulo arithmetic (obviously), problem is, I'm getting quite weird results when negative numbers are involved:
-1 % 4 = -1
-1 % 4U = 3
So far, so good.
-1 % 4000 = -1
(-1+4000U) % 4000U = 3999
(-1) % 4000U = 3295
Question: The value (3295) does hold for the (a/b)*b + a%b shall equal a, truncated towards zero (for a=-1, b=4000) from C standard (6.5.5#6) so it's not a bug per se, but why is the standard defined this way?! Surely, there must be some logic in this...
How do I have to write a%b to get sensible results for negative a (as (a+b)%b stops working when abs(a)>b)?
Test application:
#include <stdio.h>
int main(int argc, char **argv) {
int i=0;
#define MAX_NUM 4000U
int weird = (i-1)%MAX_NUM;
printf("%i\n", weird);
printf("%i\n", (i-1+MAX_NUM))%MAX_NUM);
printf("a: %i, b: %i, a from equation: %i\n", i-1, MAX_NUM,
((i-1)/MAX_NUM)*MAX_NUM + weird);
return 0;
}
Arithmetic in C always (short of some oddities with bit shift operators) promotes all operands to a common type before performing the operation. Thus:
(-1) % 4000U
is promoted as (assuming 32 bit ints):
0xffffffffu % 4000u
which yields 3295.
If you want to use modular arithmetic for array offsets that could be negative, you first need to abandon using unsigned arithmetic on the offsets. As such, your results will now be in the range -MAX_NUM+1 to MAX_NUM-1, due to C's ugly definition of signed integer division and remainder. If the code is not performance critical, just add if (result<0) result+=MAX_NUM; and be done with it. If you really need to avoid the branch (and you've measured to determine that you need to avoid it) then ask again how to optimize this computation and myself or someone brighter than me on SO will surely be able to help. :-)
As 6.5.3 says, "The usual arithmetic conversions are performed on the operands." In the case of your example:
(-1) % 4000U
that means converting the -1 into an unsigned int. Your -1, therefore, is really being interpreted as 4294967295... for which the remainder is exactly what you're seeing: 3295.
The "Usual arithmetic conversions" are described in 6.3.1.8.

Modulus with a negative number

Possible Duplicates:
Modulus operation with negatives values - weird thing ??
Mod of negative number is melting my brain!
I tried doing 25 % -9 just for fun and the answer I got was -2 (this was on Google) and when I did this in C code I got 7. Can someone explain me why two different answers?
In C89/90, either result was allowed. The results you got from division and remainder were required to "fit" together so that (a/b)*b + a%b == a.
Starting with C99, integer division with a negative input is required to truncate toward zero. The relationship between the results from division and remainder is still required though. This means that (in effect) the result from the remainder operation always has the same sign as the left operand, so 25 % -9 must yield 7, not -2.
For what it's worth, C++ followed roughly the same path, just a few years behind C. C++98/03 has the same rules as C89/90, so for your inputs the remainder could be either negative or positive (but still needs to fit together with the result from division). Starting with C++11, it requires the same behavior as C99, so 25 % - 9 == 7.
Some other languages (e.g., Python) require that the result from remainder have the same sign as the right operand instead.
If you come to think about it in a mathematical base of 9 they are the same thing as 9-2 = 7

Resources