Why does Java's % operator give different results than my calculator for a negative dividend?

两盒软妹~` 提交于 2019-12-01 20:08:29

问题


How come on a calculator -1 mod 26 = 25, but in C or Java -1 % 26 == -1. I need a program which solves it like the calculator. Is there a difference between the two?


回答1:


Both answers (25 and -1) are valid. It's just that different systems have different conventions.

The one I see the most common (in mathematics) is:

quotient  = floor(x / y)
remainder = x - quotient * y

Where floor() is to round towards negative infinity.

This is the convention that your calculator is giving you. (Mathematica also uses this convention.)

The one I think most programming languages use is:

quotient  = integerpart(x / y)
remainder = x - quotient * y

Where integerpart() is the same as a (float -> integer) cast. (round towards zero)

Some conventions like to keep the remainder the same sign as one of the operands.

The same thing applies to the sign of the divider. Different conventions are different.




回答2:


"How come ... ?"

There are two common definitions of the modulo operation. Java has chosen one ("same sign as dividend") and the calculator implements another; presumably "same sign as divisor", though you'd need to do some experiments to be sure.

In fact, the Wikipedia page on the modulo operation gives 4 different definitions of the operator that are used by different programming languages. (And some programming languages give you two operators with different semantics.)

In the case of C, the definition depends on the version of the C standard you are talking about. For ISO C 1999, the modulo operator follows the same definition as Java. For earlier versions of the C standard, the semantics of % are implementation dependent

"Is there a difference between the two?"

Obviously there is!

"I need a program which solves it like the calculator."

Feel free to write one :-).

But if you just want to know how to get the "same sign as divisor" form of modulus in Java, here's one way:

int otherModulus = (a % b) + (a < 0 ? b : 0);  // works for b > 0.

int otherModulus = (a % b) +                   // works for b != 0
                   (b > 0 ? (a < 0 ? b : 0) : (a > 0 ? -b : 0));



回答3:


Modulo arithmetic with negative operands is different in different languages, and is upto the language definition to drive. In Java, Modulus is more like Remainder.

Generally, if you want to get a negative number for negative inputs then you can use this:

int r = x % n;
if (r > 0 && x < 0)
{
    r -= n;
}

Or, if you were using a language that returns a negative number on a negative input and you would prefer positive:

int r = x % n;
if (r < 0)
{
    r += n;
}

So, based on what you need as the desired result, I recommend you use the appropriate implementation rather than relying on the language to compute for you.

Also, note that what the result should be in the case of Java is described authoratively in the JLS: in the section 15.17.3 - Remainder Operator %. They give a motivation there (that a%b should be such that (a/b)*b+(a%b) is equal to a) but it is the inclusion of that section in the JLS that makes the result so.



来源:https://stackoverflow.com/questions/7479526/why-does-javas-operator-give-different-results-than-my-calculator-for-a-negat

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!