负整数间是怎么整除和取余数的呢?
数学上貌似没定义,但计算机确实能算。于是就试了试,想总结一下规律。
一不小心发现,C/C++ 和 Python 下的结果是不同的:
C/C++ |
Python |
精确值 |
|
---|---|---|---|
-14/3 |
-4 |
-5 |
-4.67 |
-14%3 |
-2 |
1 |
/ |
14/-3 |
-4 |
-5 |
-4.67 |
14%-3 |
2 |
-1 |
/ |
-14/-3 |
4 |
4 |
4.67 |
-14%-3 |
-2 |
-2 |
/ |
总结规律如下:
- 两种语言中,商和余数都符合 被除数=商x除数+余数 这一数学规律。
- 两种语言中,整除的方法不同:C/C++ 是向零取整(负数向上、正数向下取整),Python 是下取整。
以 n/3 和 n%3 为例,看看这两种处理方法的区别。
C 的情况,两种运算结果都关于0对称和反号:
n | -5 | -4 | -3 | -2 | -1 | 0 | +1 | +2 | +3 | +4 | +5 |
商 | -1 | -1 | -1 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 1 |
余数 | -2 | -1 | 0 | -2 | -1 | 0 | 1 | 2 | 0 | 1 | 2 |
Python 的情况,运算结果是完全连续的:
n | -5 | -4 | -3 | -2 | -1 | 0 | +1 | +2 | +3 | +4 | +5 |
商 | -2 | -2 | -1 | -1 | -1 | 0 | 0 | 0 | 1 | 1 | 1 |
余数 | 1 | 2 | 0 | 1 | 2 | 0 | 1 | 2 | 0 | 1 | 2 |
不知道那种在数学上更好用。个人觉得 Python 的处理方式更优美一些吧。
至于其他语言的处理方法,应该也出不了这两种。我所知道的:
- C/C++ “向零取整式整除”:C/C++、Java、bash
- Python “下取整式整除”:Python、Perl、Lua
2013年4月21日 21:09
刚才无意中看到一篇文章 http://ceeji.net/blog/mod-in-real
在评论里看到,这是两种除法的定义方式。
2013年5月07日 17:27
其实不完全正确。在 C99 之前 C 语言的取整是未定义的,不同架构上不同的编译器都可能导致完全不同的结果,而且这个结果多半是在这种硬件上最快的。
2013年5月08日 09:13
@比尔盖子: 我在K&R的书上看到一段代码,认定C是向零取整的。请问,准确的C语言规范应该在哪里查?谢谢了。
2013年5月17日 18:20
C 语言规范请查阅 C89 (ANSI C) 和 C99 的 ISO 文档。K&R 第二版是 ANSI C,有些对于 C99 来说已经不正确了。
C89 中,-22 / 7 = -3, -22 % 7 = -1,也可以-22 / 7= -4, -22 % 7 = 6。 而C99中明确为 -22 / 7 = -3, -22 % 7 = -1,只有一种结果。
2013年5月19日 08:35
@比尔盖子: 谢谢。我回头去啃文档
2013年6月08日 18:56
python3有些不同了
cecil@cecil-Aspire-4750:~$ python3
Python 3.2.3 (default, Oct 19 2012, 20:13:42)
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> -14/3
-4.666666666666667
>>> -14%3
1
2013年6月08日 20:09
@ceclinux: python3里,你要写 -14//3
>>> -14//3
-5
2013年6月08日 20:10
@endle:
初学python,谢谢了
2013年6月30日 13:27
很基础,总结的不错
2013年8月16日 14:42
很多语言都有点相关,但是在运算时总是又有差异。我做app的时候,以常遇到这些问题。思路是很好的
2013年9月09日 09:59
这个在Graham & Knuth的"Concrete Mathematics"里有讲过,书里的定义结果是向下取整。记得Guido van Rossum也写过一篇文章讲原因。
a mod b = a - b * floor(a / b)
书中floor(x)的定义本身也为向下(负无穷方向)取整。
2013年9月09日 10:03
记错了。
http://python-history.blogspot.com/2010/08/why-pythons-integer-division-floors.html
2013年9月29日 17:36
这样算好像有语法错误,中断结果
2014年1月01日 20:21
两数相除,同号得正,异号得负,并把绝对值相除,0除以任何一个不等于0的数,都得0.
很明显在数学方面来看取整应该是向0的,因为0没有符号.
判断的时候判断模比较符合数学规则,显然pyhon有点问题