Python笔记|取整那些事
在Python中,以下三个概念经常被混淆,即:整除、int()函数、round()函数。
故摊主通过查阅Python文档、上机实操,对这几个概念的细节进行了详细验证。
整除运算 //
基础知识
在Python中,x // y
中 //
称为「运算符(Operator)」, x
与 y
称为「运算对象」(Operand)。
Operator 可以翻译成 运算符/操作符,Operand 可以翻译成 运算对象/操作数。
《高中信息技术必修一》课本中,Operator 翻译成运算符,Operand无明确翻译。
- 在Python中,
//
运算的结果表现为「向下取整」。
问:如何理解「向下取整」?答:数轴上的「向左取整」
//
两边操作数的类型可以为「整型(int)」或者「实型(float)」
以下三个部分,按照课本内容,只需掌握第一部分和第四部分即可。中间两个部分学有余力的同学做拓展了解。
一、运算对象x、y 均为整型
当运算对象 x、y 均为整型时,x // y
的结果也为整型(int)。
正负关系 | x // y |
---|---|
正 // 正 | 9 // 2 = 4 9 // 3 = 3 |
正 // 负 | 9 // -2 = -5 9 // (-2) = -5 9 // -3 = -3 |
负 // 正 | -3 // 2 = -2 -1 // 2 = -1 -3 // 1 = -3 |
负 // 负 | -1 // -2 = 0 -3 // -2 = 1 -3 // -3 = 1 |
拓展提问:如何验证结果也为整型?
回答:使用
type()
函数验证即可输入:
print(type(9//2))
输出结果为:
<class 'int'>
二、运算对象x、y 均为实型
当运算对象 x、y 均为实型时,x // y
的结果也为实型(float)。
正负关系 | x // y |
---|---|
正 // 正 | 9.0 // 2.0 = 4.0 9.0 // 3.0 = 3.0 9.0 // 3.5 = 2.0 9.1 // 3.0 = 3.0 |
正 // 负 | 9.0 // -2.0 = -5.0 9.0 // (-2.0) = -5.0 9.0 // -3 = -3.0 9.0 // -3.1 = -3.0 |
负 // 正 | -3.0 // 2.1 = -2.0 -1.0 // 2.0 = -1.0 -3.0 // 1.0 = -3.0 |
负 // 负 | -1.0 // -2.0 = 0.0 -3.0 // -2.0 = 1.0 -3.0 // -3.0 = 1.0 |
拓展提问:如何验证结果也为实型?
回答:使用
type()
函数验证即可输入:
print(type(-1.0//-2.0))
输出结果为:
<class 'float'>
三、运算对象x、y 为实型、整型混合
当运算对象 x、y 均为实型时,x // y
的结果也为实型(float)。
正负关系 | x // y |
---|---|
正 // 正 | 9.0 // 2 = 4.0 9 // 3.0 = 3.0 9 // 3.5 = 2.0 9 // 3.0 = 3.0 |
正 // 负 | 9.0 // -2.0 = -5.0 9.0 // (-2.0) = -5.0 9.0 // -3 = -3.0 9.0 // -3.1 = -3.0 |
负 // 正 | -3.0 // 2.1 = -2.0 -1.0 // 2.0 = -1.0 -3.0 // 1.0 = -3.0 |
负 // 负 | -1.0 // -2.0 = 0.0 -3.0 // -2.0 = 1.0 -3.0 // -3.0 = 1.0 |
四、常见报错信息
案例 | 错误类型 | 备注 |
---|---|---|
9 // ‘3’ | TypeError: unsupported operand type(s) for //: ‘int’ and ‘str’ | 整型 // 字符串型 是不合法的 |
9 // 0 | ZeroDivisionError: float floor division by zero | 除数为零 |
int(x) 函数
基础知识
在Python中,int(x)
函数的功能是将一个值转换成十进制整数。
- 若
x
为整型,则返回x
的十进制整数。 - 若
x
为实型,则丢掉x
的小数部分,返回x
的整数部分。 - 若
x
为字符串型,int()
表现为int(x, base=10)
。(字符串x
中的内容是base进制整数
)- 当
x
为正确的base进制整数
时,则返回其对应的十进制整数。- 对于字符串
x
的细节要求,详见 官方文档
- 对于字符串
- 否则,产生报错。
- 当
Python官方文档 - int():https://docs.python.org/3/library/functions.html#int
一、x为整型
若 x
为整型,则返回 x
的十进制整数。
案例 | 返回值 |
---|---|
int(5) | 5 |
int(-5) | 5 |
int(0b111) | 7 |
int(-0b1000) | -8 |
int(0o10) | 8 |
int(-0o11) | -9 |
int(0xa) | 10 |
int(-0xA) | -10 |
int(0) | 0 |
int(-0) | 0 |
二、x为实型
若 x
为实型,则丢掉 x
的小数部分,返回 x
的整数部分。
案例 | 返回值 |
---|---|
int(5.5) | 5 |
int(5.0) | 5 |
int(-5.5) | -5 |
int(-5.0) | -5 |
int(0.0) | 0 |
int(-0.00) | 0 |
三、x为字符串型
若 x
为字符串型,int()
表现为 int(x, base=10)
。(字符串 x
中的内容是 base进制整数
)
- 当
x
为正确的base进制整数
时,返回其对应的十进制整数。- 对于字符串
x
的细节要求,详见 官方文档
- 对于字符串
- 否则,产生报错。
案例 | 返回值 |
---|---|
int(“123”) | 123 |
int(“-123”) | -123 |
int(“0”) | 0 |
int(“000”) | 0 |
int(“-000”) | 0 |
int(“00123”) | 123 |
int(“12300”) | 12300 |
int(“-123”) | -123 |
int(“-00123”) | -123 |
int(“-12300”) | -12300 |
int(“111”, 2) | 5 |
int(“1000”, 2) | 8 |
int(“10”, 8) | 8 |
int(“A”, 16) | 10 |
int(“f”, 16) | 15 |
🚀 特别注意
- 若
x
为字符串型,但是字符串的内容是合法的实型(如 “123.0”、”0.00”),则int(x)
会产生ValueError
的报错信息
- int(123.3) 是合法的,但是 int(“123.3”) 是不合法的。
- 只有当
x
为字符串类型时,才能添加参数base
。(即当x
为整型/实型时,不能指定参数base
)
- int(“111”, 2) 是合法的,但是 int(111, 2) 是不合法的。
- int(“0b111”)是不合法的,但是 int(0b111) 是合法的。
- 关于「前缀零」
- int(00123) 是不合法的,但是 int(“00123”) 是合法的。
三、常见报错信息
案例 | 错误类型 |
---|---|
int(“abcd”) | ValueError: invalid literal for int() with base 10: ‘abcd’ |
int(“ab123cd”) | ValueError: invalid literal for int() with base 10: ‘ab123cd’ |
int(“123.0”) | ValueError: invalid literal for int() with base 10: ‘123.0’ |
int(“0.00”) | ValueError: invalid literal for int() with base 10: ‘0.00’ |
int(00123) | SyntaxError: leading zeros in decimal integer literals are not permitted; use an 0o prefix for octal integers |
int(“0b111”) | ValueError: invalid literal for int() with base 10: ‘0b111’ |
int(111, 2) | TypeError: int() can’t convert non-string with explicit base |
round(x) 函数
round half to even策略
round(x)
函数的功能在《必修一》课本P80的表格中,被定义为「对 x
进行四舍五入」。但是在实际的Python语法中,这样的定义是 有争议的。
对于非 形如*.5 的数字,这样的定义没有争议。
- 即 round(1.499999) → 1、round(1.5001) = 2、round(2.5000001) → 3
但是对于 形如*.5 的数字,这样的定义是有争议的。
- 在我们的理解中,形如 *.5 的浮点数,应当被取到 *+1 。
- 但是在Python中,round(2.5) → 2、round(3.5) = 4、round(4.5) → 4
实际上,Python采用了一种叫「round half to even」的策略(该策略也被称为「banker’s rounding」),将形如 *.5 的浮点数舍取到最近的偶数。(中文翻译有「四舍六入五留双」)
Python为什么采用「round half to even」的策略❓
试想有一组数字:1.5、2.5、3.5、4.5
有以下三种策略,round up、round down、round half to even:
round up:1.5 → 2、2.5 → 3、3.5 → 4、4.5 → 5
round down:1.5 → 1、2.5 → 2、3.5 → 3、4.5 → 4
round half to even:1.5 → 2、2.5 → 2、3.5 → 4、4.5 → 4
现在要求对该组数字进行 round 操作,并进行求和
- 采用「round up」 或者 「round down」策略时,会使得 sum 的结果 偏大/偏小。
- 采用「round up to half」的策略时,sum 的结果相对来说误差最小(在这个案例中甚至没有误差)
所以,Python中采取了「round up to half」策略来定义 round() 函数,来减小舍入误差。
案例 | 返回值 |
---|---|
round(1) | 1 |
round(-1) | -1 |
round(1.5) | 2 |
round(2.5) | 2 |
round(-1.5) | -2 |
round(-2.5) | -2 |
round(0) | 0 |
round(0.0) | 0 |
浮点数表示的精度差异
https://docs.python.org/3/tutorial/floatingpoint.html#tut-fp-issues
round()返回值类型
Python 官方文档 - round()
Python官方文档 - round():https://docs.python.org/3/library/functions.html#round
round(number, ndigits=None)
Return number rounded to ndigits precision after the decimal point. If ndigits is omitted or is
None
, it returns the nearest integer to its input.For the built-in types supporting
round()
, values are rounded to the closest multiple of 10 to the power minus ndigits; if two multiples are equally close, rounding is done toward the even choice (so, for example, bothround(0.5)
andround(-0.5)
are0
, andround(1.5)
is2
). Any integer value is valid for ndigits (positive, zero, or negative). The return value is an integer if ndigits is omitted orNone
. Otherwise, the return value has the same type as number.For a general Python object
number
,round
delegates tonumber.__round__
.The behavior of
round()
for floats can be surprising: for example,round(2.675, 2)
gives2.67
instead of the expected2.68
. This is not a bug: it’s a result of the fact that most decimal fractions can’t be represented exactly as a float. See Floating Point Arithmetic: Issues and Limitations for more information.
参考资料
- Python int() Function:https://www.geeksforgeeks.org/python-int-function/
- How is int() implemented in Python?:https://stackoverflow.com/questions/38542263/how-is-int-implemented-in-python
- why does (00123 + 34351) return 34434 in javascript, java and python ? The correct answer is 34474:https://stackoverflow.com/questions/63254469/why-does-00123-34351-return-34434-in-javascript-java-and-python-the-corre
- https://docs.python.org/3/library/functions.html#int