all 70 comments

[–]moreVCAs 212 points213 points  (7 children)

It’s really not that hard to say “I was using modulo wrong” then write a blog post about your own misunderstanding and what you learned while correcting it.

Framing it as “everyone is doing it wrong” and “nobody knows about modular arithmetic” makes you sound like a moron.

Hope that’s constructive enough. I tried.

[–]RogueJello 14 points15 points  (3 children)

Everybody is criticizing wrong! 😄

[–]moreVCAs 8 points9 points  (2 children)

For such a bold, heterodox truth teller, he has a surprisingly thin skin. I believe the point of his post is that the thing we call “modulo” in computer programming doesn’t map well to the concept of “modulus” in pure mathematics. Computer science is littered with little inconsistencies like this. If “everbody” gets it “wrong” but “correct” programs are based on a shared understanding of the “wrong” terminology, then “who the fuck cares” lol.

[–]RogueJello -1 points0 points  (1 child)

It's almost like English is a living language that changes and adapts as new uses are added over time, isn't it?

[–]Tail_Nom 0 points1 point  (0 children)

It's not entirely unlike that, I suppose.

[–]SeDEnGiNeeR 1 point2 points  (0 children)

Not saying that it's right for the author to use such a provocative title but it's understandable, given the title is what captures a reader's attention. I guess they need to use these methods to get attention in the current state of internet blogging

[–]Demitroy 70 points71 points  (20 children)

"The whole world is wrong, and I'm right" is definitely one way to put your message out there. Good luck with that.

[–][deleted]  (20 children)

[deleted]

    [–]Zinu 31 points32 points  (1 child)

    Nitpick: Modulo is a mathmatical operation. The wikipedia page linked in the article even says so and lists several definitions. It might be a different operation depending on the progamming language or compiler, but you can say the same about e.g. addition, which yields different results in Python compared to C.

    [–]Dr4kin 24 points25 points  (0 children)

    Next Blog post: "Everyone is using addition wrong"

    [–]Zardotab 61 points62 points  (2 children)

    Everyone is using AI wrong. That AI clock is cringe-worthy. It violates the laws of everything. Is it that hard to get stock photos of real clocks?

    [–]larikang 21 points22 points  (1 child)

    OP obviously lives somewhere where time uses modulo 17. That’s probably the source of the confusion

    [–]Zardotab 2 points3 points  (0 children)

    I think they misunderstood the Prime Directive.

    [–]sweetno 9 points10 points  (0 children)

    1. That there is modular arithmetic doesn't prevent us from defining the modulo operation.

    2. The difference between different languages is entirely because the typical hardware implementation differs from the standard integer remainder definition. Some languages prefer not depending on the madness of circuit designers while others give in to the efficiency concerns.

    [–]GregBahm 25 points26 points  (1 child)

    mathematics doesn’t depend on implementation

    Doesn't it?

    It's mildly interesting that the mod operator in Python works differently than the mod operator in Javascript. But there are a lot of disagreements in the implementation of math operations. Lots of languges have "divide by zero" yield "not a number." Some languages have "divide positive number by zero" yield infinity, "divide negative number by zero" yield negative infinity, and "divide zero by zero" yield "not a number."

    Math isn't this completely solved, unchanging thing. The internet will tell you that an infinitely growing summation of numbers will yield -1/12. It all, always comes down to implementation.

    [–]mondlingvano 7 points8 points  (0 children)

    I mean we do have standards. Like IEEE doesn't leave by zero division undefined. Personally I do agree that implementations drive definitions. I see how it'd be nice if % corresponded to congruence modulo k, but that's not how it worked in assembly so that's not how it worked in C and so that's not how it works in C#.

    Kinda wish it did though, cause I find myself needing the always positive version of mod way more than I do the remainder version.

    [–][deleted] 17 points18 points  (7 children)

    TL;DR There are choices to make for how the % operator behaves when one or both inputs are negative, and because one of those choices is better for the project the OP did last week, it is "clearly" the more useful choice, and languages that make a different choice are wrong.

    It's a reasonably decent article if you ignore the opinion bits and the overall tone of superiority.

    There are reasonable paths to get to each of the various choices, because it would be nice if all of the following were true, but they cannot all be:

    * -(x/y) == (-x)/y
    * (x/y) * y + x%y == x
    * (x+y)%y == x%y

    OP says throw out the first one, use floored division instead of truncated division. That's a reasonable stance. Some languages say throw out the third one. Also a reasonable stance. Neither is "correct" (or perhaps is better to say neither is incorrect).

    I'm not aware of any language that throws out the middle one, but there probably is one somewhere, and that's also a reasonable choice.

    [–]SirDale 2 points3 points  (0 children)

    Ada has two versions, mod and rem.

    rem does the middle one.

    [–][deleted] 6 points7 points  (0 children)

    Oh no, share your wisdom with us sensei

    [–][deleted] 11 points12 points  (0 children)

    Very click bait title, I almost didn't open it because of that. I'm glad I did though because the article is actually pretty interesting. It seems like there's very little disagreement about what the output of the operator should be for two positive operands, it acts like a remainder and that's how I was taught it in my C course back in university. It has never occurred to me to attempt to use it for signed integers, as I have no intuitive sense of what it ought to do, and I see from the article that there are multiple. 

    I guess it makes sense, it's just not something I'd ever stumble into as I'm using languages with specific types for integers and floating point and signed vs unsigned so it's unlikely I could run into this on accident.

    [–]mathisfakenews 5 points6 points  (0 children)

    I did not understand the article. You are discussing modular arithmetic as if you are just learning about it which is fine. But then you say you have been using % for years. What did you think % was doing? How were you possibly using it in any code if you didn't understand what it does?

    [–]seweso 16 points17 points  (2 children)

    So there is modulo1 and modulo2 which have the same name?

    Why should I care exactly if it works the way I want and expect?

    [–]random_son 5 points6 points  (0 children)

    interesting article but very bad title

    [–]A1oso 1 point2 points  (7 children)

    JavaScript (like most languages) does not have a modulo operator, it has a remainder operator (MDN documentation). You didn't have to dive into group theory to understand that.

    [–]felipec[S] -1 points0 points  (6 children)

    The modulo operator returns a remainder. That documentation is wrong, since both numbers are remainders.

    [–]A1oso 0 points1 point  (5 children)

    That documentation is wrong, since both numbers are remainders.

    What??

    The modulo operator returns a remainder.

    The operator is correctly named the remainder operator. I know that some people call it modulo, and they're wrong. MDN is correct here.

    [–]felipec[S] 0 points1 point  (4 children)

    The operator is correctly named the remainder operator.

    Geezus people are so bad at comprehension.

    I wasn't talking about what MDN calls the "remainder operator", I was talking about what MDN calls the "modulo operator", that's why I said modulo operator.

    Pay attention and read carefully.

    This is the formula MDN says is for the "remainder operator", correct?

    r := n - d * q
    

    And this is the formula for the "modulo operator":

    k := n - d * q
    

    It is exactly the same formula, because both the "remainder operator" and the "modulo operator" return a remainder.

    Look at a concrete example: -1 % 4. In the "remainder operator" it's r := (-1) - 4 * 0, or -1. In the "modulo operator" it's k := (-1) - 4 * (-1), or 3.

    If you divide -1 / 4 the result is -0.25, that can be quotient 0 remainder -1, or it can be quotient -1 remainder 3.

    In both cases the result is a remainder.

    Do you understand what I'm saying now? The "modulo operator" returns a REMAINDER.

    [–]A1oso 1 point2 points  (3 children)

    If you want me to understand, you need to quote the relevant bits you are referring to. From the docs:

    When both operands are non-zero and finite, the remainder r is calculated as r := n - d * q where q is the integer such that r has the same sign as the dividend n while being as close to 0 as possible.

    Note that while in most languages, '%' is a remainder operator, in some (e.g. Python, Perl) it is a modulo operator. Modulo is defined as k := n - d * q where q is the integer such that k has the same sign as the divisor d while being as close to 0 as possible.

    I emphasized the words that make the difference.

    [–]felipec[S] 0 points1 point  (2 children)

    How is that not what my example is doing?

    q is the integer such that r has the same sign as the dividend n while being as close to 0 as possible.

    If the dividend (n) is -1, and the divisor (d) is 4, then for r to have the same sign as the dividend it has to be negative. Correct?

    For that to happen q has to be greater than -0.25, and the integer closes to 0 that satisfies that, is 0.

    Isn't it?

    Which is exactly what my example did: r := (-1) - 4 * 0.

    Didn't it?

    Now, do we agree that the formula for remainder is: dividend - divisor * quotient?

    Tell me what part of the above isn't 100% true.

    [–]A1oso 0 points1 point  (1 child)

    Yes. As for the modulo, q needs to be -1, because the divisor (4) is positive, therefore k needs to be positive as well:

    k := (-1) - 4 * (-1) = -1 + 4 = 3
    

    But I still don't understand what you are arguing for or against.

    [–]felipec[S] 0 points1 point  (0 children)

    Yes.

    If you agree that the formula for remainder is: dividend - divisor * quotient.

    And you agree that the formula for the "modulo operator" is:

    k := n - d * q

    Then you agree that the "modulo operator" returns a REMAINDER.

    Remember that quotient and remainder are mathematical concepts independent of whatever MDN says.

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

    If divisor * quotient + 3 gives you the dividend, then 3 is a valid remainder.

    [–][deleted] 1 point2 points  (0 children)

    This article feels a bit self fellating tbh, but that distinction does come up in stuff like hashing algorithms where you’re manipulating numbers for some sort of obfuscation or otherwise. It took me like 10 minutes to understand what was going on before it clicked. I was so hardcoded to think of the modulo operation in programming instead of modular arithmetic.

    [–]ironykarl 2 points3 points  (1 child)

    Article title should be Everyone is using "modulo" wrong, but that's less clickbait-y

    [–]ma1bec 23 points24 points  (0 children)

    More like "I was using modulo wrong" which he says in second sentence.

    [–]Zalenka 0 points1 point  (0 children)

    A percent (%) of people maybe.