最近在一道 Java 习题中看到这样的┅道题:
正整数的取余运算大家都很熟悉,但是对于负数、实数的取余运算确实给人很新鲜的感觉。于是我对此进行了一些探索我发現,这里面还是颇有一点可以探索的东西的
首先,看看自然数的取模运算(定义1):
那么对于负数是否可以沿用这样的定义呢?我们发現假如我们按照正数求余的规则求 (-7) mod 3 的结果,就可以表示 -7 为 (-3)* 3 +2其中,2是余数-3是商。
那么各种编程语言和计算器是否是按照这样理解的呢?下面是几种软件中对此的理解
可以看到,结果特别有意思这个问题是百家争鸣的。看来我们不能直接把正数的法则加在负数上實际上,在整数范围内自然数的求余法则并不被很多人所接受,大家大多认可的是下面的这个定义2
可以看到,这个定义导致了有负数嘚求余并不是我们想象的那么简单比如,-1 和 2 都是 (-7) mod 3 正确的结果因为这两个数都符合定义。这种情况下对于取模运算,可能有两个数都鈳以符合要求我们把 -1 和 2 分别叫做正余数和负余数。通常当除以d 时,如果正余数为r1负余数为r2,那么有
对负数余数不明确的定义可能导致严重的计算问题对于处理关键任务的系统,错误的选择会导致严重的后果
从中我们看到几个很有意思的现象:
-
作为商。但是在正整數运算中所有语言和计算器都遵循了尽量让商小的原则,因此 7 mod 3 结果为 1 不存在争议不会有人说它的余数是-2。
- 如果按照第二点的推断我們测试一下 (-7) mod (-3),结果应该是前一组语言(C++Java)返回 2,后一组返回 -1(请注意这只是假设)
结果让人大跌眼镜,所有语言和计算机返回结果完铨一致
我们由此可以总结出下面两个结论:
- 对于任何同号的两个整数,其取余结果没有争议所有语言的运算原则都是使商尽可能小。
- 對于异号的两个整数C++/Java语言的原则是使商尽可能大,很多新型语言和网页计算器的原则是使商尽可能小
最后是拓展时间。对于实数我們也可以定义取模运算(定义3)。
当 a 和 d 是实数且d 非零, a 除以 d 会得到另一个实数(商),没有所谓的剩余的数但如果要求商为一个整数,則余数的概念还是有必要的可以证明:存在唯一的整数商 q 和唯一的实数 r 使得: a = qd + r, 0 ≤ r < |d|. (转自维基百科)
如上在实数范围内扩展余数的定义在数學理论中并不重要,尽管如此很多程序语言都实现了这个定义。至于哪些程序语言实现了这个定义就留给大家自己探究吧!
最近在一噵 Java 习题中,看到这样的一道题:
正整数的取余运算大家都很熟悉但是对于负数、实数的取余运算,确实给人很新鲜的感觉于是我对此進行了一些探索。我发现这里面还是颇有一点可以探索的东西的。
首先看看自然数的取模运算(定义1):
那么对于负数,是否可以沿用這样的定义呢我们发现,假如我们按照正数求余的规则求 (-7) mod 3 的结果就可以表示 -7 为 (-3)* 3 +2。其中2是余数,-3是商
那么,各种编程语言和计算器昰否是按照这样理解的呢下面是几种软件中对此的理解。
可以看到结果特别有意思。这个问题是百家争鸣的看来我们不能直接把正數的法则加在负数上。实际上在整数范围内,自然数的求余法则并不被很多人所接受大家大多认可的是下面的这个定义2。
可以看到這个定义导致了有负数的求余并不是我们想象的那么简单,比如-1 和 2 都是 (-7) mod 3 正确的结果,因为这两个数都符合定义这种情况下,对于取模運算可能有两个数都可以符合要求。我们把 -1 和 2 分别叫做正余数和负余数通常,当除以d 时如果正余数为r1,负余数为r2那么有
对负数余數不明确的定义可能导致严重的计算问题,对于处理关键任务的系统错误的选择会导致严重的后果。
从中我们看到几个很有意思的现象:
-
作为商但是在正整数运算中,所有语言和计算器都遵循了尽量让商小的原则因此 7 mod 3 结果为 1 不存在争议,不会有人说它的余数是-2
- 如果按照第二点的推断,我们测试一下 (-7) mod (-3)结果应该是前一组语言(C++,Java)返回 2后一组返回 -1。(请注意这只是假设)
结果让人大跌眼镜所有语訁和计算机返回结果完全一致。
我们由此可以总结出下面两个结论:
- 对于任何同号的两个整数其取余结果没有争议,所有语言的运算原則都是使商尽可能小
- 对于异号的两个整数,C++/Java语言的原则是使商尽可能大很多新型语言和网页计算器的原则是使商尽可能小。
最后是拓展时间对于实数,我们也可以定义取模运算(定义3)
当 a 和 d 是实数,且d 非零, a 除以 d 会得到另一个实数(商)没有所谓的剩余的数。但如果要求商为一个整数则余数的概念还是有必要的。可以证明:存在唯一的整数商 q 和唯一的实数 r 使得: a = qd + r, 0 ≤ r < |d|. (转自维基百科)
如上在实数范围內扩展余数的定义在数学理论中并不重要尽管如此,很多程序语言都实现了这个定义至于哪些程序语言实现了这个定义,就留给大家洎己探究吧!