3
30
2013
14

负整数的整除和取余运算

负整数间是怎么整除和取余数的呢?

数学上貌似没定义,但计算机确实能算。于是就试了试,想总结一下规律。

一不小心发现,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 /

总结规律如下:

  1. 两种语言中,商和余数都符合 被除数=商x除数+余数 这一数学规律。
  2. 两种语言中,整除的方法不同: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
Category: 计算机 | Tags: python c/c++ 编程 数学 | Read Count: 10855
Avatar_small
endle 说:
2013年4月21日 21:09

刚才无意中看到一篇文章 http://ceeji.net/blog/mod-in-real
在评论里看到,这是两种除法的定义方式。

Avatar_small
比尔盖子 说:
2013年5月07日 17:27

其实不完全正确。在 C99 之前 C 语言的取整是未定义的,不同架构上不同的编译器都可能导致完全不同的结果,而且这个结果多半是在这种硬件上最快的。

Avatar_small
endle 说:
2013年5月08日 09:13

@比尔盖子: 我在K&R的书上看到一段代码,认定C是向零取整的。请问,准确的C语言规范应该在哪里查?谢谢了。

Avatar_small
比尔盖子 说:
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,只有一种结果。

Avatar_small
endle 说:
2013年5月19日 08:35

@比尔盖子: 谢谢。我回头去啃文档

Avatar_small
ceclinux 说:
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

Avatar_small
endle 说:
2013年6月08日 20:09

@ceclinux: python3里,你要写 -14//3
>>> -14//3
-5

Avatar_small
ceclinux 说:
2013年6月08日 20:10

@endle:
初学python,谢谢了

Avatar_small
什么值得买 说:
2013年6月30日 13:27

很基础,总结的不错

Avatar_small
龙腾天下 说:
2013年8月16日 14:42

很多语言都有点相关,但是在运算时总是又有差异。我做app的时候,以常遇到这些问题。思路是很好的

Avatar_small
yousong 说:
2013年9月09日 09:59

这个在Graham & Knuth的"Concrete Mathematics"里有讲过,书里的定义结果是向下取整。记得Guido van Rossum也写过一篇文章讲原因。

a mod b = a - b * floor(a / b)

书中floor(x)的定义本身也为向下(负无穷方向)取整。

Avatar_small
yousong 说:
2013年9月09日 10:03

记错了。

http://python-history.blogspot.com/2010/08/why-pythons-integer-division-floors.html

Avatar_small
韩语 说:
2013年9月29日 17:36

这样算好像有语法错误,中断结果

Avatar_small
Brilliance 说:
2014年1月01日 20:21

两数相除,同号得正,异号得负,并把绝对值相除,0除以任何一个不等于0的数,都得0.
很明显在数学方面来看取整应该是向0的,因为0没有符号.
判断的时候判断模比较符合数学规则,显然pyhon有点问题


登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter

| Theme: Aeros 2.0 by TheBuckmaker.com