locked
Modulo RRS feed

  • Question

  • in my opinion the modulo implementation has a bug, since, for example (-1)%60 should be 59 instead of -1, since the modulo of a number MUST BE greater or equal then 0.
    Friday, April 20, 2018 9:12 PM

Answers

  • in my opinion the modulo implementation has a bug, since, for example (-1)%60 should be 59 instead of -1, since the modulo of a number MUST BE greater or equal then 0.

    Hi,

    no, there's no "must be" for the modulo-*Operator*. See: https://en.wikipedia.org/wiki/Modulo_operation for Details (c#: Result has same sign as the dividend).

    Regards,

      Thorsten



    Friday, April 20, 2018 9:39 PM

All replies

  • in my opinion the modulo implementation has a bug, since, for example (-1)%60 should be 59 instead of -1, since the modulo of a number MUST BE greater or equal then 0.

    Hi,

    no, there's no "must be" for the modulo-*Operator*. See: https://en.wikipedia.org/wiki/Modulo_operation for Details (c#: Result has same sign as the dividend).

    Regards,

      Thorsten



    Friday, April 20, 2018 9:39 PM
  • This is one of those quirky things about mathematics in general that can be problematic to adjust to.

    When we get taught division and remainders, it is often in terms of positive divisors and dividends. The general accepted form of the division, where a is the dividend, d is the divisor, q is the quotient and r is the remainder is

    a = qd + r

    If a is negative then qd must be negative, so what about the remainder? Let's use your example, where the dividend is -1 and the divisor is 60

    -1 = (0)(60) + r

    If r was to be positive, this would mean that for negative numbers the quotient would have to move one more across the number line

    -1 = (-1)(60) + 59

    But this breaks the mirror that it has with positive division

    1 = (0)(60) + 1

    This means there would have to be one rule for positive division:

    a = qd + r

    and another for negative division:

    a = (q-1)d + r

    If you switch the remainder to negative numbers when you divide a negative number by a positive number, or a positive number by a negative, you end up with that same thing working for both positive and negative multiplication.

    Also remember what the remainder means, for positive numbers the + remainder takes it away from zero. So for 1/60 the result is 0 remainder 1, or 0 + 1. For negative numbers a positive number would take the number towards zero, which is why you would need to subtract that extra from the quotient. To have it mirror correctly you would need to subtract to move away from zero on the negative part of the number line.


    This is a signature. Any samples given are not meant to have error checking or show best practices. They are meant to just illustrate a point. I may also give inefficient code or introduce some problems to discourage copy/paste coding. This is because the major point of my posts is to aid in the learning process.

    • Edited by Darran Rowe Saturday, April 21, 2018 1:48 AM
    Saturday, April 21, 2018 1:47 AM
  • As a follow up to this, it is documented how the remainder is calculated.

    The C# reference is here. For interest, the C++ version shows that they basically used the same method.

    It is also convention that the remainder ends up this way. The signed division processor instruction (idiv) is documented as:

    "Non-integral results are truncated (chopped) towards 0."

    This generally means that when the processor does a signed integer divide, the quotient will always go towards 0. For example, say we have 3/2 and (-3)/2. Dividing by a negative works the same way but it is more annoying to think about.

    For 3/2, the processor will prefer the 1r1 answer over the 2r(-1) answer. If you multiply the quotient by the divisor, you get:

    qd = 1 * 2 = 2

    So when it does the division, it prefers the quotient closer to 0, and so the remainder will be the difference between this quotient and the actual dividend. In the same way, for (-3)/2, the processor prefers the (-1)r(-1) answer over the (-2)r1 answer. Again if you multiply the quotient by the divisor, you get:

    qd = (-1) * 2 = -2

    So it again, the quotient closer to 0 has been chosen.

    As an interesting quirk though, you cannot properly trust the sign of the remainder. For (-1)/60, the remainder is -1, however, for 1/(-60) the remainder should actually be 1. Yes, positive 1. So the remainder given is still the remainder for the quotient closer to 0, but the sign chosen depends on the dividend and not the divisor. This is what the x86 processor gives as the remainder for the idiv instruction too.


    This is a signature. Any samples given are not meant to have error checking or show best practices. They are meant to just illustrate a point. I may also give inefficient code or introduce some problems to discourage copy/paste coding. This is because the major point of my posts is to aid in the learning process.

    Saturday, April 21, 2018 11:08 AM
  • in my opinion the modulo implementation has a bug, since, for example (-1)%60 should be 59 instead of -1, since the modulo of a number MUST BE greater or equal then 0.

     

    First I thought, is there modula in .Net this is the general questions forum 

    https://en.wikipedia.org/wiki/Modula-2

    :-)

    But it seems to be in ILS 

    The problem is handled here on Github

     https://github.com/fsharp/fslang-suggestions/issues/417

    And yes it is the same in VB and  it is even very old in that (older than Visual versions). On that GitHub page is exact described why it does not change. 

    Which means that if it occurs to you, you have to create your own method to get the modulo. 


    Success
    Cor









    Saturday, April 21, 2018 2:10 PM
  • This article describes several definitions of the modulo operation:

    https://en.wikipedia.org/wiki/Modulo_operation

    In some definitions, the modulo is always positive (as per Raymond Boute), in others it has the same sign as the divisor (as per Donald Knuth). But note the possible pitfalls in the later case, for example when testing if an integer is odd. In PowerShell the result has the same sign as the dividend. The definition used varies with programming language and hardware.


    Richard Mueller - MVP Enterprise Mobility (Identity and Access)

    Saturday, April 28, 2018 12:48 PM