java如何进行负数的模计算?

发布于 2024-10-06 14:01:04 字数 94 浏览 10 评论 0原文

我做模数错了吗?因为在 Java 中 -13 % 64 的计算结果为 -13 但我想得到 51

Am I doing modulus wrong? Because in Java -13 % 64 evaluates to -13 but I want to get 51.

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

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

发布评论

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

评论(15

橘香 2024-10-13 14:01:05

如何在 C 或 C++ 中仅获取正模数(因为 % 运算符允许负数)

Java 以及 C 和 C++ 似乎都以这种方式表现类似。在不提出新问题的情况下,我还想介绍 C 和 C++ 的方法。

来自我的 modulus_of_positive_and_negative_integers.c ://github.com/ElectricRCAircraftGuy/eRCaGuy_hello_world" rel="nofollow noreferrer">eRCaGuy_hello_world 存储库:

/// A function to perform and return the mathematical modulus as returned by
/// programming calculators and Google. In other words, it will **always**
/// return a positive value, unlike the `%` remainder operator in C!
/// Example:
/// So, `-5 % 180` in C or C++ is `-5`, but `mathematical_modulo(-5, 180)`
/// is the same as "-5 mod 180" in a calculator or on Google, and is `175`.
int mathematical_modulo(int num1, int num2)
{
    int mod = num1 % num2;
    if (mod < 0)
    {
        mod += num2;
    }

    return mod;
}

上述代码的示例测试:

请注意 -10 % 180 生成 - 10 在 C 和 C++ 中,因为 % 运算符的作用类似于简单的余数,而不是翻转模,而 mathematical_modulo(-10, 180) 产生 < code>170,因为在本例中下溢会返回到最大值 180,然后再次向下 10 步。

printf("-10 %% 180 = %4i\n", -10 % 180);
printf("  0 %% 180 = %4i\n",   0 % 180);
printf(" 10 %% 180 = %4i\n",  10 % 180);
printf("\n");

printf("mathematical_modulo(-10, 180) = %4i\n",
        mathematical_modulo(-10, 180));
printf("mathematical_modulo(  0, 180) = %4i\n",
        mathematical_modulo(  0, 180));
printf("mathematical_modulo( 10, 180) = %4i\n",
        mathematical_modulo( 10, 180));
printf("\n");

示例输出:

-10 % 180 =  -10
  0 % 180 =    0
 10 % 180 =   10

mathematical_modulo(-10, 180) =  170
mathematical_modulo(  0, 180) =    0
mathematical_modulo( 10, 180) =   10

Linux 上的计算器工具

在 C 或 C++ 中,-10 % 180-10。但是,在我的 Linux 计算器上,-10 mod 180170

在此处输入图像描述

浏览器中的 Google 计算器

在 Google 上,-10 % 180 -10 mod 180(Google 上的情况相同)也是 170

在此处输入图像描述

参考资料

  1. 我自己的实验通过上面链接的我的代码进行学习和自学。
  2. JavaScript %(模)对于负数给出负结果
  3. 这个答案:java如何对负数进行模数计算?

How to get only positive modulus numbers in C or C++ (since the % operator allows negative numbers)

Java and C and C++ all appear to act similarly in this manner. Without opening a new question, I'd like to present the approach for C and C++ as well.

From modulus_of_positive_and_negative_integers.c in my eRCaGuy_hello_world repo:

/// A function to perform and return the mathematical modulus as returned by
/// programming calculators and Google. In other words, it will **always**
/// return a positive value, unlike the `%` remainder operator in C!
/// Example:
/// So, `-5 % 180` in C or C++ is `-5`, but `mathematical_modulo(-5, 180)`
/// is the same as "-5 mod 180" in a calculator or on Google, and is `175`.
int mathematical_modulo(int num1, int num2)
{
    int mod = num1 % num2;
    if (mod < 0)
    {
        mod += num2;
    }

    return mod;
}

Sample tests of the code above:

Notice that -10 % 180 produces -10 in C and C++ since the % operator acts like a simple remainder, not a roll-over modulo, whereas mathematical_modulo(-10, 180) produces 170, since the underflow wraps back around to the max value of 180 in this case, and then down 10 steps again.

printf("-10 %% 180 = %4i\n", -10 % 180);
printf("  0 %% 180 = %4i\n",   0 % 180);
printf(" 10 %% 180 = %4i\n",  10 % 180);
printf("\n");

printf("mathematical_modulo(-10, 180) = %4i\n",
        mathematical_modulo(-10, 180));
printf("mathematical_modulo(  0, 180) = %4i\n",
        mathematical_modulo(  0, 180));
printf("mathematical_modulo( 10, 180) = %4i\n",
        mathematical_modulo( 10, 180));
printf("\n");

Sample output:

-10 % 180 =  -10
  0 % 180 =    0
 10 % 180 =   10

mathematical_modulo(-10, 180) =  170
mathematical_modulo(  0, 180) =    0
mathematical_modulo( 10, 180) =   10

Calculator tool on Linux

In C or C++, -10 % 180 is -10. But, on my Linux calculator, -10 mod 180 is 170:

enter image description here

Google calculator in browser

On Google, -10 % 180, or -10 mod 180 (same thing on Google) are both 170 as well:

enter image description here

References

  1. My own experimentation, learning, and self-study via my code linked-to above.
  2. JavaScript % (modulo) gives a negative result for negative numbers
  3. This answer: How does java do modulus calculations with negative numbers?
愁以何悠 2024-10-13 14:01:05

我认为 Java 在这种情况下不会返回 51。我在 Mac 上运行 Java 8,我得到:

-13 % 64 = -13

程序:

public class Test {
    public static void main(String[] args) {
        int i = -13;
        int j = 64;
        System.out.println(i % j);
    }
}

I don't think Java returns 51 in this case. I am running Java 8 on a Mac and I get:

-13 % 64 = -13

Program:

public class Test {
    public static void main(String[] args) {
        int i = -13;
        int j = 64;
        System.out.println(i % j);
    }
}
2024-10-13 14:01:04

负数模的两种定义都在使用 - 有些语言使用一种定义,有些则使用另一种定义。

如果你想为负输入获得负数,那么你可以使用这个:

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

同样,如果你使用的语言在负输入上返回负数,并且你更喜欢正数:

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

Both definitions of modulus of negative numbers are in use - some languages use one definition and some the other.

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

Likewise 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;
}
桃酥萝莉 2024-10-13 14:01:04

由于“数学上”两者都是正确的:

-13 % 64 = -13 (on modulus 64)  
-13 % 64 = 51 (on modulus 64)

Java 语言开发人员必须选择其中一个选项,他们选择了:

结果的符号等于被除数的符号。

Java 规范中这样说:

https://docs。 oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.17.3

Since "mathematically" both are correct:

-13 % 64 = -13 (on modulus 64)  
-13 % 64 = 51 (on modulus 64)

One of the options had to be chosen by Java language developers and they chose:

the sign of the result equals the sign of the dividend.

Says it in Java specs:

https://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.17.3

世界和平 2024-10-13 14:01:04

您确定您正在使用 Java 工作吗?因为 Java 给出了预期的 -13 % 64 = -13 。分红的标志!

Are you sure you are working in Java? 'cause Java gives -13 % 64 = -13 as expected. The sign of dividend!

允世 2024-10-13 14:01:04

请注意,此答案适用于问题的先前不同版本。

您的结果对于 Java 来说是错误的。
请提供一些您是如何得出这个结论的背景(您的程序、Java 的实现和版本)。

来自 Java 语言规范< /a>

15.17.3 余数运算符 %

[...]

二进制数值提升后的整数操作数的余数运算(第 5.6.2 节)生成一个结果值,使得 (a/b)*b+(a%b) 等于 a。

15.17.2 除法运算符 /
[...]
整数除法向 0 舍入。

由于 / 向零舍入(结果为零),因此在这种情况下 % 的结果应为负数。

Note that this answer was for a previous, different version of the question.

Your result is wrong for Java.
Please provide some context how you arrived at it (your program, implementation and version of Java).

From the Java Language Specification

15.17.3 Remainder Operator %

[...]

The remainder operation for operands that are integers after binary numeric promotion (§5.6.2) produces a result value such that (a/b)*b+(a%b) is equal to a.

15.17.2 Division Operator /
[...]
Integer division rounds toward 0.

Since / is rounded towards zero (resulting in zero), the result of % should be negative in this case.

再浓的妆也掩不了殇 2024-10-13 14:01:04

你可以使用

(x % n) - (x < 0 ? n : 0);

you can use

(x % n) - (x < 0 ? n : 0);
酸甜透明夹心 2024-10-13 14:01:04

你的答案在维基百科上:
取模运算

说明了Java中取模运算的符号与被除数的符号相同。由于我们正在讨论除法运算的其余部分,因此在您的情况下它返回 -13,因为 -13/64 = 0。-13-0 = -13。

编辑:抱歉,误解了你的问题......你是对的,java应该给出-13。能提供更多周边代码吗?

Your answer is in wikipedia:
modulo operation

It says, that in Java the sign on modulo operation is the same as that of dividend. and since we're talking about the rest of the division operation is just fine, that it returns -13 in your case, since -13/64 = 0. -13-0 = -13.

EDIT: Sorry, misunderstood your question...You're right, java should give -13. Can you provide more surrounding code?

面犯桃花 2024-10-13 14:01:04

具有负操作数的模算术由语言设计者定义,他们可能会将其留给语言实现,而语言实现可能会将定义推迟到 CPU 架构。

我无法找到 Java 语言定义。
感谢 Ishtar,Java 语言规范 剩余部分运算符 % 表示结果的符号与分子的符号相同。

Modulo arithmetic with negative operands is defined by the language designer, who might leave it to the language implementation, who might defer the definition to the CPU architecture.

I wasn't able to find a Java language definition.
Thanks Ishtar, Java Language Specification for the Remainder Operator % says that the sign of the result is the same as the sign of the numerator.

天赋异禀 2024-10-13 14:01:04

为了克服这个问题,您可以将 64 (或任何您的模数基数)添加到负值,直到它为正。

int k = -13;
int modbase = 64;

while (k < 0) {
    k += modbase;
}

int result = k % modbase;

结果仍将处于相同的等价类中。

To overcome this, you could add 64 (or whatever your modulus base is) to the negative value until it is positive

int k = -13;
int modbase = 64;

while (k < 0) {
    k += modbase;
}

int result = k % modbase;

The result will still be in the same equivalence class.

风和你 2024-10-13 14:01:04

x = x + m = x - m(模数 m)。
因此,模数 64 中的 -13 = -13 + 64 和模数 64 中的 -13 = 51
假设 Z = X * d + r,如果 0 r < X 然后在除法 Z/X 中,我们将余数称为 r
Z % X 返回 Z/X 的余数。

x = x + m = x - m in modulus m.
so -13 = -13 + 64 in modulus 64 and -13 = 51 in modulus 64.
assume Z = X * d + r, if 0 < r < X then in division Z/X we call r the remainder.
Z % X returns the remainder of Z/X.

风流物 2024-10-13 14:01:04

mod 函数定义为一个数字超过不大于该数字的除数的最大整数倍的量。因此,在您的情况下,

-13 % 64

不超过 -13 的 64 的最大整数倍是 -64。现在,当您从 -64 中减去 -13 时,它等于 51 -13 - (-64) = -13 + 64 = 51

The mod function is defined as the amount by which a number exceeds the largest integer multiple of the divisor that is not greater than that number. So in your case of

-13 % 64

the largest integer multiple of 64 that does not exceed -13 is -64. Now, when you subtract -13 from -64 it equals 51 -13 - (-64) = -13 + 64 = 51

匿名。 2024-10-13 14:01:04

在我的 Java JDK 1.8.0_05 -13%64=-13 版本中,

你可以尝试 -13-(int(-13/64))
换句话说,除法转换为整数以去掉小数部分
然后从分子中减去
因此 numerator-(int(numerator/denominator)) 应该给出正确的余数 &符号

In my version of Java JDK 1.8.0_05 -13%64=-13

you could try -13-(int(-13/64))
in other words do division cast to an integer to get rid of the fraction part
then subtract from numerator
So numerator-(int(numerator/denominator)) should give the correct remainder & sign

海未深 2024-10-13 14:01:04

在 Java 最新版本中,您会得到 -13%64 = -13。答案总是带有分子符号。

In Java latest versions you get -13%64 = -13. The answer will always have sign of numerator.

栀子花开つ 2024-10-13 14:01:04

根据 JLS 第 15.17.3 节,“二进制数字提升后整数操作数的余数运算产生的结果值使得 (a/b)*b+(a%b) 等于 a。
即使在特殊情况下,这个恒等式也成立,即被除数是其类型的最大可能的负整数,除数是 -1(余数为 0)。”

希望有所帮助。

According to section 15.17.3 of the JLS, "The remainder operation for operands that are integers after binary numeric promotion produces a result value such that (a/b)*b+(a%b) is equal to a.
This identity holds even in the special case that the dividend is the negative integer of largest possible magnitude for its type and the divisor is -1 (the remainder is 0)."

Hope that helps.

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