强基初中数学&学Python——第198课 Python内置函数详解数学篇之六:abs/round/divmod


  abs(x)函数 

  返回一个数的绝对值。参数必选,可以是整数、浮点数或任何实现了 __abs__() 的对象。如果参数是一个复数,则返回它的模。

>>>abs(-123)

123

>>>abs(-12.3e4)

123000.0

>>>abs(1+1j)

1.4142135623730951

>>>class AbsTest:

    def __abs__(self):

        return -123

>>>abs(AbsTest())

-123

>>>class AbsTest2:

    def __index__(self):

        return -123

>>>abs(AbsTest2())

Traceback (most recent call last):

  File "<stdin>", line 1, in <module>

TypeError: bad operand type for abs(): 'AbsTest2'

注意:abs()原样返回对象的__abs__()的值。

 

  round()函数

  调用方法1:一个数参数,round(number)。

  整数参数直接返回该整数,浮点或分数参数返回最接近输入值的整数,复数发生TypeError异常。

>>>round(1.504)

2

>>>round(-1.504)

-2

>>>round(1.494)

1

>>>round(-1.494)

-1

>>>round(123)

123

>>>round(-123)

-123

>>>from fractions import Fraction

>>>round(Fraction(5,3))

2

>>>round(float(Fraction(5,3)))

2

>>>round(1+1j)

Traceback (most recent call last):

  File "<stdin>", line 1, in <module>

TypeError: type complex doesn't define __round__ method

  调用方法2:一个数参数和一个整数精度参数,round(number, ndigits)。

  如果number是分数,先转为整数或浮点数。

  经过分数检查转换后,如果number为整数,当ndigits≥0,不做任何处理;当number位数相反数<ndigits<0,从个位开始数,四舍五入到abs(ndigits)位——abs(ndigits)+1位保留,第abs(ndigits)位四舍五入,以0占位;当ndigits≤number位数相反数,结果为0

  如果number为浮点数,当ndigits=0,四舍五入为整数;当ndigits>0,四舍五入到小数点后ndigits位,若ndigits≥number原小数点后位数,则什么没做;ndigits<0,处理方法与整数相同。

  把结果转化为与原number类型相同后返回。

>>>round(12345,2)

12345

>>>round(12345,0)

12345

>>>round(12345,-2)

12300

>>>round(12345,-5)

0

>>>round(-12345,2)

-12345

>>>round(-12345,0)

-12345

>>>round(-12345,-2)

-12300

>>>round(-12345,-5)

0

>>>round(12345.6789,2)

12345.68

>>>round(12345.6789,0)

12346.0

>>>round(12345.6789,-2)

12300.0

>>>round(-12345.6789,2)

-12345.68

>>>round(-12345.6789,0)

-12346.0

>>>round(-12345.6789,-2)

-12300.0

>>>round(1.2, 2)

1.2

>>>round(1.2, -2)

0.0

>>>round(-1.2, 2)

-1.2

>>>round(-1.2, -2)

-0.0

>>>from fractions import Fraction

>>>round(Fraction(500,3),2)

Fraction(16667, 100)

>>>round(Fraction(500,3),0)

Fraction(167, 1)

>>>round(Fraction(500,3),-2)

Fraction(200, 1)

>>>round(Fraction(500,3),-3)

Fraction(0, 1)

>>>round(-Fraction(500,3),2)

Fraction(-16667, 100)

>>>round(-Fraction(500,3),0)

Fraction(-167, 1)

>>>round(-Fraction(500,3),-2)

Fraction(-200, 1)

>>>round(-Fraction(500,3),-3)

Fraction(0, 1)

  调用方法3:一个对象参数,round(obj)。

  只返回obj.__round__()的调用。

  程序代码(文本代码附录1):

 

  运行结果:

 

  程序代码

 

  运行结果:

 

 

  先观察下面的运行结果:

>>>round(2.675,2)

2.67

  为何结果是2.67而不是期望的 2.68呢?难道程序出错了?

  我们在后面加一个很小的数看看结果如何。

>>>round(2.67500000001,2)

2.68

  可见,这不算是程序错误,这是由于一般二进制不能精确表示十进制小数造成。这个问题以后再讨论。

 

  divmod()函数

  参数两个,必选,按位。

  调用方式1:两个整数,divmod(intNum1,intNum2)。

  返回商和余数,即 (intNum1//intNum2intNum1%intNum2),可知第二参数不能为0。

>>>divmod(123, 17)

(7, 4)

>>>divmod(-123, 17)

(-8, 13)

>>>divmod(123, -17)

(-8, -13)

>>>divmod(-123, -17)

(7, -4)

  调用方式2:两个浮点数(如果其中有一个是浮点数,就当作2个浮点数),divmod(floatNum1,floatNum2)。

  余数p=floatNum1 % floatNum2,

  商q=round((floatNum1 - p) / floatNum2)

  返回(q, p)。

  验证上面整数的结果:

>>>p=123 % 17

>>>q=round((123-p)/17)

>>>(q,p)

(7, 4)

>>>p=-123 % 17

>>>q=round((-123-p)/17)

>>>(q,p)

(-8, 13)

>>>p=123 % -17

>>>q=round((123-p)/-17)

>>>(q,p)

(-8, -13)

>>>p=-123 % -17

>>>q=round((-123-p)/-17)

>>>(q,p)

(7, -4)

  采用浮点数参数,验证与调用:

>>>p=12.3 % 7

>>>q=round((12.3-p)/7)

>>>(q,p)

(1, 5.300000000000001)

>>>divmod(12.3, 7)

(1.0, 5.300000000000001)

>>>p=123 % .7

>>>q=round((123-p)/.7)

>>>(q,p)

(175, 0.5000000000000078)

>>>divmod(123, .7)

(175.0, 0.5000000000000078)

>>>p=-12.3 % 0.17

>>>q=round((-12.3-p)/.17)

>>>(q,p)

(-73, 0.11000000000000018)

>>>divmod(-12.3, 0.17)

(-73.0, 0.11000000000000018)

>>>p=-12.3 % -0.17

>>>q=round((-12.3-p)/-.17)

>>>(q,p)

(72, -0.05999999999999983)

>>>divmod(-12.3, -0.17)

(72.0, -0.05999999999999983)

 

  如果余数不为0,那么它一定与除数同符号,以被除数的符号无关。

 

  练习题:

1、写出下面代码的打印结果(问号处)并拷贝测试。

>>>abs(-314)

?

>>>abs(-3.14e10)

?

>>>abs(3-4j)

?

>>>class ATest:

    def __abs__(self):

        return -99.9

>>>abs(ATest())

?

2、写出下面代码的打印结果(问号处)并拷贝测试。

>>>round(3.601)

?

>>>round(-3.601)

?

>>>from fractions import Fraction

>>>round(Fraction(17,5))

?

3、写出下面代码的打印结果(问号处)并拷贝测试。

>>>round(67891,-2)

?

>>>round(67891,-5)

?

>>>round(-67891,-2)

?

>>>round(-67891,-5)

?

>>>round(-12345.6789,3)

?

>>>round(-45365.6789,0)

?

>>>round(-12345.6789,-3)

?

>>>round(-1.2, -2)

?

>>>from fractions import Fraction

>>>round(Fraction(-500,7),3)

?

>>>round(Fraction(-500,7),0)

?

>>>round(Fraction(--5000,7),-2)

?

>>>round(Fraction(-5000,9),-3)

?

4、写出下面代码的打印结果(问号处)并拷贝测试。

>>>class RTest:

?

class RTest:

...     def __init__(self,num=123.456):

.         self.num=num

..     def __round__(self,ndigits=None):

           return round(self.num,ndigits)

>>>print(round(RTest(-123.456), -3))

?

5、写出下面代码的打印结果(问号处)并拷贝测试。

>>>divmod(189, 15)

?

>>>divmod(-189, 15)

?

>>>divmod(189, -15)

?

>>>divmod(-189, -15)

?

6、写出下面代码的打印结果(问号处)并拷贝测试。

>>>divmod(17.7, 5)

?

>>>divmod(2.17, .7)

?

>>>divmod(-18.7, 0.13)

?

>>>divmod(-18.7, -0.13)

?

 

附录1:

#round对象测试

class RTest:

    def __init__(self,num=123.456):

        self.num=num

    def __round__(self,ndigits=None):

        return round(self.num,ndigits)

        

print(round(RTest(), 2))

print(round(RTest()))

print(round(RTest(), -2))

print(round(RTest(), -3))

print(round(RTest(-123.456), 2))

print(round(RTest(-123.456)))

print(round(RTest(-123.456), -2))

print(round(RTest(-123.456), -3))