我对那些忽略了模运算的数学定义的编程语言(Java,C……)很好奇。
为什么在模运算中返回负值(根据定义应该总是返回正数)?有何意义?
a
和b
之间的欧几里得关系也是相同的(除了C语言没有针对INT_MIN % -1
的特殊情况——这是未定义的行为)。 - cafINT_MIN / -1
可能由于整数溢出而未定义,但似乎余数仍应为零。然而,我可以通过那个操作让gcc
发出SIGFPE
信号... - cafINT_MIN / -1
由于有符号整数溢出而导致未定义行为,就像 INT_MAX + 1
一样。草案中引用的新语言特别指出 %
运算符的 行为 是未定义的。 - caf来自 维基百科 (我的强调):
给定两个正数,a(被除数)和n(除数),a模n(简写为a mod n)可以视为在a被n整除时的余数。例如,“5 mod 4”的表达式将计算结果为1,因为5被4除后余数为1,而“9 mod 3”的结果将计算为0,因为9被3除后余数为0;在乘以3次3之后,9没有需要减去的部分了。(请注意,用计算器执行除法不会显示此操作所引用的结果,商将表示为小数。)当a或n为负数时,这个朴素的定义就会失效,编程语言在如何定义这些值方面存在差异。虽然通常使用整数作为a和n的数据类型,但许多计算系统允许其他类型的数字操作数。 对于n的整数取模的数字范围是0到n-1。(n mod 1始终为0;n mod 0未定义,可能导致计算机编程语言中的“除以零”错误)有关在数论中应用的更古老和相关的约定,请参见模运算。
n=qd+r
,其中 0≤r<d
。 :-) - R.. GitHub STOP HELPING ICEA rem B := A - (A div B) * B
A div B
为trunc(A/B)
,则得到C的%
运算符。如果定义A div B
为floor(A/B)
,则得到Python的%
运算符。其他定义也是可能的。/
如何处理负数。它留给硬件来处理。abs(A) div abs(B)
,并在(A < 0) xor (B < 0)
的情况下翻转符号。返回模数的负值的实用原因可能是硬件指令实现模数。
因此,标准将其定义不清,以便编译器可以执行对它们更简单的操作。
/
运算符定义的,其行为现在对于负值已经有了明确定义。 - Oliver Charlesworth在 C 或 Java 标准中,%
不被称为模运算符,而是返回 余数。
它被定义为对于负被除数返回负数,以便关系式 (a/b)*b + a%b == a
成立,只要 a / b
是可表示的。由于除法运算符被定义为向零截断,这限制了余数的符号。
(a/b)*b+a%b==a
,并且除法朝着零截断。 - Oliver Charlesworth%
的定义,胜过于C99。 - dan04