问题描述
今天在工作中,我与一位同事进行了有趣的讨论.当他发生以下事情时,他感到惊讶:
Today at work I had an interesting discussion with one of my coworkers. He was surprised when he had the following happen to him:
assert(-1 % 10 == -1) //Expecting 9
因此,当他来问我这个问题时,我告诉他很好,这是有道理的.将-1除以10时,您得到0,剩下的-1.但是他的论点是模运算符应该坚持永远是积极的"模型.我做了一点研究,发现他指的模数看起来像这样:
So when he came to ask me about it, I told him "well, that makes sense. When you divide -1 by 10, you get 0 with -1 remaining. His argument however was that the modulus operator is supposed to hold true to the "always positive" model. I did a little research and found that the modulus he was referring to looks like this:
a = n * q + r
a = n * q + r
I 使用的定义似乎是模数的Knuth版本,即:
The definition I was using, however, appears to be the Knuth version of modulus, which is:
r = a-n * q
r = a - n * q
所以,我的问题是,为什么它以FORTRAN标准(以及后来的C标准)结尾而使模数运算符截断为0?在我看来,称其为模数"而不是余数"是不恰当的(在数学上,答案实际上应该是9).这与硬件的划分方式有关吗?
So, my question is why it ended up in the FORTRAN standard (and subsequently the C-standard) to have the modulus operator truncate toward 0? It seems like a misnomer to me to call it "modulus" and not "remainder" (In math, the answer really should be 9). Is this related to how hardware is doing the division?
供参考:
- 有关Modulus的维基百科
- 模数"运算符上的MSDN条目
(是的,我意识到它是针对VS2003的...我目前仍坚持使用它.Sadface) - 模运算符更改
- 不要假设正余数...
- Wikipedia on Modulus
- MSDN entry on the "modulus" operator
(Yes, i realize its for VS2003...I'm stuck with it currently. Sadface) - Modulus operator changes
- Don't assume positive remainder...
TLDR;硬件是模数运算符向0截断的原因吗?
推荐答案
C将其称为%运算符,并将其结果称为余数. C ++从C复制它.两种语言都没有将其称为模运算符.这也解释了为什么余数为负的原因:因为/运算符会截断为0,并且(a / b) * b + (a % b)
应该等于a
.
C calls it the % operator, and calls its result the remainder. C++ copies this from C. Neither language calls it the modulus operator. This also explains why the remainder is negative: because the / operator truncates towards 0, and (a / b) * b + (a % b)
should equal a
.
编辑:DavidRodríguez正确地指出C ++ 确实定义了一个模板类std::modulus
,该类称为operator%
.我认为,该类的名字很差.稍微挖掘一下,它是从STL继承而来的,它现在已经被命名. STL的下载内容为:"STL是在SGI MIPSproTM C ++ 7.0、7.1、7.2和7.2.1上开发的."据我所知,实际上没有编译器和硬件,MIPSpro会将其划分给CPU和处理器. MIPS硬件将截断为0,这意味着std::modulus
始终被错误命名.
Edit: David Rodríguez rightly points out that C++ does define a template class std::modulus
, which calls operator%
. In my opinion, that class is poorly named. Digging a little bit, it is inherited from STL where it was already named as it is now. The download for STL says "The STL was developed on SGI MIPSproTM C++ 7.0, 7.1, 7.2, and 7.2.1.", and as far as I can tell without actually having the compiler and hardware, MIPSpro passes the division to the CPU and MIPS hardware truncates to 0, which would mean std::modulus
has always been misnamed.
这篇关于为什么将运算符%称为“模数"?而不是“剩余"运算符操作员?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!