为什么 Java 的 % 运算符对于负股息给出的结果与我的计算器不同?

发布于 2024-12-05 10:33:51 字数 102 浏览 0 评论 0原文

为什么计算器上是 -1 mod 26 = 25,但在 C 或 Java 中却是 -1 % 26 == -1。我需要一个像计算器一样解决这个问题的程序。两者有区别吗?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

玉环 2024-12-12 10:33:51

两个答案(25 和 -1)都是有效的。只是不同的系统有不同的约定。

我看到最常见的(在数学中)是:

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

其中 floor() 是向负无穷大舍入。

这是计算器为您提供的约定。 (Mathematica 也使用这一约定。)

我认为大多数编程语言使用的约定是:

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

其中 integerpart() 与 (float -> integer) 强制转换相同。 (向零舍入)

一些约定喜欢使余数与操作数之一保持相同的符号。

同样的情况也适用于分隔符的符号。不同的约定是不同的。

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.

甜心小果奶 2024-12-12 10:33:51

“怎么会...?”

模运算有两种常见的定义。 Java 选择了一个(“与被除数相同的符号”)并且计算器实现了另一个;大概是“与除数相同的符号”,尽管您需要做一些实验才能确定。

事实上,模运算上的维基百科页面给出了 4 种不同的运算符定义,供不同的编程语言。 (某些编程语言为您提供了两个具有不同语义的运算符。)

对于 C,定义取决于您所讨论的 C 标准的版本。对于 ISO C 1999,模运算符遵循与 Java 相同的定义。对于早期版本的 C 标准,% 的语义依赖于实现

“两者之间有区别吗?”

显然有!

“我需要一个像计算器一样解决这个问题的程序。”

请随意编写一个:-)。

但如果你只是想知道如何在 Java 中获得“与除数相同的符号”形式的模数,这里有一种方法:

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));

"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));
时光是把杀猪刀 2024-12-12 10:33:51

带负操作数的模运算在不同的语言中是不同的,并且由语言定义来驱动。在Java中,更像是余数

一般来说,如果您想为负输入获得负数,那么您可以使用以下命令:

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

或者,如果您使用的语言在负输入上返回负数,并且您更喜欢正数:

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

因此,根据您的需要为了达到预期的结果,我建议您使用适当的实现,而不是依赖语言来为您计算。

另请注意,JLS:在第 15.17.3 节中 - 余数运算符 %。他们在那里给出了一个动机(a%b 应该使得 (a/b)*b+(a%b) 等于 a),但正是 JLS 中包含该部分才使得结果如此。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文