加载中...

Python笔记|取整那些事


Python笔记|取整那些事

在Python中,以下三个概念经常被混淆,即:整除、int()函数、round()函数。

故摊主通过查阅Python文档、上机实操,对这几个概念的细节进行了详细验证。

整除运算 //

基础知识

在Python中,x // y// 称为「运算符(Operator)」, xy 称为「运算对象」(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进制整数 时,则返回其对应的十进制整数。
    • 否则,产生报错。

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进制整数 时,返回其对应的十进制整数。
  • 否则,产生报错。
案例 返回值
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() 函数,来减小舍入误差。

参考资料:https://youtu.be/wSEBoZ4CcDw?si=D_YiXdyYIPbcMLNI

案例 返回值
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, both round(0.5) and round(-0.5) are 0, and round(1.5) is 2). Any integer value is valid for ndigits (positive, zero, or negative). The return value is an integer if ndigits is omitted or None. Otherwise, the return value has the same type as number.

For a general Python object number, round delegates to number.__round__.

The behavior of round() for floats can be surprising: for example, round(2.675, 2) gives 2.67 instead of the expected 2.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.

参考资料


文章作者: Rickyの水果摊
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Rickyの水果摊 !
  目录