为什么C和Ruby之间的模运算符(%)的行为对于负整数是不同的?

Aal*_*lok 2 c ruby math implementation modulo

我在这里运行一些代码.我试过了-40 % 3.它给了我输出2.当我在C中执行相同的操作时,我得到:

int i = (-40) % 3
printf("%d", i);
Run Code Online (Sandbox Code Playgroud)

输出是

-1
Run Code Online (Sandbox Code Playgroud)

两种语言如何在内部执行模运算?

hac*_*cks 5

维基说:

给定两个正数,a(被除数)和n(除数),模n(缩写为mod n)是欧几里得分的剩余部分a by n.
.... 当任何一个a或者n是否定的时候,天真的定义就会破裂,编程语言在如何定义这些值方面会有所不同.


现在的问题是,为什么-40 % 32在Ruby或者换句话说,什么是它背后的数学?

让我们从欧几里德分部开始,该分部指出:

给定两个整数,a并且n,有n ? 0,存在唯一的整数,q并且r,a = n*q + r0 ? r < |n|,其中|n|表示绝对值n.

现在请注意商的两个定义:

1. Donald Knuth描述了浮动除法,其中商由地板函数定义,q=floor(a/n)其余r
在此输入图像描述

这里的商(q)总是向下舍入(即使它已经是负数),余数(r)与除数的符号相同.

2. 一些实现将商定义为

q = sgn(a)floor(|a| / n) whre sgn是符号函数.

并且余数(r)与被除数(a)具有相同的符号.

现在一切都取决于q:

  • 如果实现符合定义1并定义q为is 和is floor(a/n)的值.这就是Ruby的情况. 40 % 31-40 % 32
  • 如果实现符合定义2并定义qsgn(a)floor(|a| / n),那么40 % 3is 1-40 % 3is 的值-1.这似乎是C和Java的情况.