1

在 python3 中使用地板除法时(也可能在 python2 中使用import __future__):

>>> 2//2
1

输出是预期的整数。但是一旦一个操作数是一个浮点数,你就会得到一个浮点数

>>> 2.0//2.0
1.0
>>> 2.0//2
1.0
>>> 2//2.0
1.0

我想这是故意的,但实际上我不明白,为什么它应该是这样的。作为始终产生整数的操作的结果,使用先前未确定的数据类型的设计概念是什么?

一个真正广泛的搜索给了我最好的(来自PEP 238

楼层划分的语义

楼层划分将在所有 Python 数字类型中实现,并将具有以下语义

   a // b == floor(a/b)

除了结果类型将是在操作之前将 a 和 b 强制转换为的通用类型。

具体来说:

- If a and b are of the same type, a//b will be of that type too.
- If the inputs are of different types, they are first coerced   
  to a common type using the same rules used for all other arithmetic operators.

In particular:

- if a and b are both ints or longs, the result has the same type and value as
  for classic division on these types (including the case of mixed input types;
  `int//long` and `long//int` will both return a long).
- For floating point inputs, the result is a float.
  For example:  `3.5//2.0 == 1.0`
- For complex numbers, // raises an exception, since floor() of a   complex number is not allowed.  
- For user-defined classes and extension types, all semantics are up  to the implementation of the class or type.

But this still doesn't explain WHY the behavior is implemented like this.

4

2 回答 2

6

One possible advantage can be the following: If the inputs of an operation are floats, then usually the most useful output type is a float, because the program is doing floating point calculations. Similarly, if the inputs of an operation are integers (ints or longs), then usually the most useful output type is an integer.

A related surprising data point:

>>> str(int(123e300 // 10.0))
'12300000000000000348405169443457756499452463917650245579212965288916278422109198944984236481408634018703901759913201583616648277756338685989513894763895354330869046350917957229381143786183918719192956157930593465276658607709014541611368487360619735051905095032755082564499801643679232993692080863707136'

It's surprising, because it's natural to expect lots of 0s at the end. You get other digits because of the limited precision of the float type.

So by returning a float, // indicates that the output can be inaccurate.

于 2014-03-05T21:16:05.333 回答
0

This makes floor division consistent with the other arithmetic operations. The advantage is that instead of remembering that // is a special case, you can use your existing knowledge and coding patterns. And as with all the other operators, if you want to force the output to be an int you should explicitly coerce it to be such.

于 2014-03-05T21:43:15.147 回答