0

I am trying to understand this function that I am debugging:

static int a = 1;

static int[] functionModulus(int n)
{
    for (; n % ++a > 0; ) ;
    return new[] {n = n/a + a >> 1, n - a};
}

Basically this function is a computation of getting an input, and will return an array with two elements such that a^2 - b^2 = n (input n). So an input of n = 15, will return 4 and 1 since 4^2 - 1^2 = 15.

Nevermind the computations, I wonder how does this exact line works:

for (; n % ++a > 0; ) ;

While debugging, the value of a at the start is 1, and my input of n = 15.

Which of course a was initialize to 1 outside the function, and 15 is my input of n. What I am puzzled is after stepping out of the for loop, the value of a becomes 3? How does it become 3? 15 mod of 3 is not greater than zero? I tried to change n to 21, and a still becomes 3 after stepping out the for loop? I cannot really understand how does it increments to 3 and how does this works.

Mateen Ulhaq
  • 24,552
  • 19
  • 101
  • 135
Willy David Jr
  • 8,604
  • 6
  • 46
  • 57
  • 2
    It increments `a` until it's a divisor of `n` – juharr Jul 12 '17 at 02:30
  • `++a` increments `a` variable before checking modulus operation during the loop. When entering the loop, `a` becomes 2 by increment, and 15 % 3 = 0 - that's why `a` value is 3 when exits the loop. – Tetsuya Yamamoto Jul 12 '17 at 02:36
  • @TetsuyaYamamoto But 15 % 3 = 0? But its not greater than zero? Since the condition it says n % a++ should be greater than zero? – Willy David Jr Jul 12 '17 at 02:38
  • 15 is dividable by 3, and 15 % 2 > 0. Note that `++a` is not same as `a++` in operator precedence manner (pre-increment vs post-increment). Check this fiddle to show how the pre-increment works: https://dotnetfiddle.net/QzWDKO. – Tetsuya Yamamoto Jul 12 '17 at 02:42

4 Answers4

2

Let's analyze this code part:

static int[] functionModulus(int n)
{
    for (; n % ++a > 0; ) ;
    return new[] {n = n/a + a >> 1, n - a};
}

There are 2 loops here:

(1) a = 1, pre-incremented by ++a that returns 2, then 15 % 2 > 0 - the loop continues.

(2) a = 2, pre-incremented by ++a that returns 3, then 15 % 3 = 0 - a value is now already 3 & the loop stops here. The array results are 4 & 1, which is correct (4^2 - 1 = 15).

If we change pre-increment to post-increment like this:

for (; n % a++ > 0; ) ;

The loop executes 3 times as follows:

(1) a = 1, then 15 % 1 > 0 - the loop continues & a will post-incremented using a++ to 2.

(2) a = 2, then 15 % 2 > 0 - the loop continues & a will post-incremented using a++ to 3.

(3) a = 3, then 15 % 3 = 0 - the loop stops here, and a value is still at 2. The array results are 4 & 2, which is incorrect (4^2 - 2^2 = 12).

So there is nothing wrong with modulus part, it depends on how value increment part works.

Conclusion: The pre-increment & post-increment may returns different results when used in a loop, there's how pre-increment (++a) preferred over post-increment (a++) here.

NB: Pre-increment increments value before next assignment or comparison, where post-increment increments value after executing an assignment/comparison.

Demo: .NET Fiddle Example

Related issue:

What is the difference between i++ and ++i?

Tetsuya Yamamoto
  • 24,297
  • 8
  • 39
  • 61
1

The line

for (; n % ++a > 0; ) ;

is equivalent to

for (; n % (a + 1) > 0; a++) ;

a++;

// n % a == 0
Mateen Ulhaq
  • 24,552
  • 19
  • 101
  • 135
1

Modulus operator returns the remainder after an integer division.

You could write the operator x % y as

result = x;
while (result >= y)
{
    result -= y;
}
return result;

In this case 15 % 3 is zero.

Kirk Broadhurst
  • 27,836
  • 16
  • 104
  • 169
1

15%3 equals 0 and fails the condition of being greater 0 this causes the for loop to terminate and the value of a is stuck at 3.

The for loop condition is executed twice once for 2 (with the left hand of the expression equal to 1) and once for 3( with the left hand of the expression equal to 0).