python数字处理技巧(1): 精度舍入、精确运算、格式化、进制数、大数打包解包、复数、NaN、分数

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/shenziheng1/article/details/83471905

1. 数字的四舍五入

当我们需要对整数 或者 浮点数进行四舍五入的时候。

  • round(value, ndigits)  /// 内置函数

对浮点数进行四舍五入(传入的ndigit应该是正值,作用于十分位、百分位...):

print( round(1.23, 1) )     # 1.2
print( round(1.27, 1) )     # 1.3
print( round(-1.27, 1) )    #-1.3
print( round(1.25361, 3))   #1.254
print( round(2.5, 0) )      #2.0 近似到最近的偶数

对整数进行四舍五入(传入的ndigit应该是自然数,作用于个位、十位、百位...)

print( round(314159, -1))    #314160
print( round(314159, -2))    #314200
print( round(314159, -3))    #314000

Comment:

不要将舍入round格式化format输出搞混淆了。 如果我们目的只是简单的输出一定宽度的数,不需要使用 round() 函数。 而仅仅只需要在格式化的时候指定精度即可。

pi = 3.1415926
print( format(pi, '0.2f')) #3.14
print( format(pi, '0.3f')) #3.142
print( 'the value is {:0.4f}'.format(pi) ) #the value is 3.1416

2. 执行精确的浮点数运算

有的时候我们需要对浮点数进行精度运算,并不希望出现小的误差。但是由于浮点数并不能精确的表示十进制数。 并且,即使是最简单的数学运算也会产生小的误差,比如:

a = 4.2 
b = 2.1 
print( a + b )      # 6.300000000000001
print( a+b == 6.3 ) #False

这些错误是由底层CPU和IEEE 754标准通过自己的浮点单位去执行算术时的特征。 由于Python的浮点数据类型使用底层表示存储数据,因此没办法去避免这样的误差

  • decimal模块  耗时但是精确

如果想更加精确(并能容忍一定的性能损耗),我们可以使用 decimal 模块:

from decimal import Decimal

a = Decimal('4.2') 
b = Decimal('2.1') 
print(a+b) # 6.3

其实呢,这段代码看起来好像有点奇怪,比如用字符串来表示数字。 然而,Decimal对象会像普通浮点数一样的工作。 我们打印它们时,看起来却跟普通数字没什么两样。

decimal 模块的一个主要特征是允许控制计算的每一方面,包括数字位数和四舍五入运算。 为了这样做,我们需要创建一个本地上下文并更改它的设置。

from decimal import localcontext

a = Decimal('1.3')
b = Decimal('1.7')
print(a / b) # 0.7647058823529411764705882353

with localcontext() as ctx:
    ctx.prec = 3
    print(a / b) # 0.765

with localcontext() as ctx:
    ctx.prec = 50
    print(a / b) #0.76470588235294117647058823529411764705882352941176

3. 数字的格式化输出

需要将数字格式化后输出,并控制数字的位数、对齐、千位分隔符和其他的细节。格式化输出单个数字的时候,可以使用内置的 format() 函数,比如:

x = 1234.56789

print(format(x, '0.2f'))     #'1234.57'
print(format(x, '>10.1f'))   #'    1234.6'
print(format(x, '<10.10f'))  #'1234.5678900000'
print(format(x, '^10.1f'))   #'  1234.6  '
print(format(x, ','))        #1,234.56789
print(format(x, 'e'))        #1.234568e+03
print('The value is {:0,.2f}'.format(x)) # The value is 1,234.57

4. 二八十六进制整数

为了将整数转换为二进制、八进制或十六进制的文本串, 可以分别使用 bin() , oct() 或 hex()函数。

x = 1234
print( bin(x) ) # 0b10011010010
print( oct(x) ) # 0o2322
print( hex(x) ) # 0x4d2

# 如果不想输出0b,0o或者0x的,使用 format() 函数
print( format(x, 'b') ) # 10011010010
print( format(x, 'o')  ) # 2322
print( format(x, 'x')  ) # 4d2

5. 字节到大整数的打包和解包

这里涉及到的是:如何将大整数利用字节进行处理。

  • int.from_bytes() & int.to_bytes()
data = b'\x00\x124V\x00x\x90\xab\x00\xcd\xef\x01\x00#\x004'
# 将bytes解析为整数,使用 int.from_bytes() 方法
print( len(data) )
print( int.from_bytes(data, 'little') )
print( int.from_bytes(data,'big') )

# 将大整数保存为字节格式使用 int.to_bytes()方法
x = 94522842520747284487117727783387188
print( x.to_bytes(16, 'big') )    # b'\x00\x124V\x00x\x90\xab\x00\xcd\xef\x01\x00#\x004'
print( x.to_bytes(16, 'little') ) # b'4\x00#\x00\x01\xef\xcd\x00\xab\x90x\x00V4\x12\x00'

大整数和字节字符串之间的转换操作并不常见。 然而,在一些应用领域有时候也会出现,比如密码学或者网络。 例如,IPv6网络地址使用一个128位的整数表示。 如果要从一个数据记录中提取这样的值的时候。

6. 复数的数学运算

  • complex(real, imag) 或者是带有后缀j的浮点数来指定
a = complex(2, 4)
b = 3 - 5j
print(a)  # (2+4j)
print(b)  # (3-5j)
print(a.real, a.imag, b.real, b.imag)  # 2.0 4.0 3.0 -5.0

7. 无穷大与NaN

Python并没有特殊的语法来表示这些特殊的浮点值,但是可以使用 float() 来创建它们。

import math
print( float('inf') )  # inf
print( float('-inf') ) # -inf
print( float('nan') )  # nan
 
a = float('inf')
print( math.isinf(a) ) # true

# 无穷大数在执行数学计算的时候会传播
print( a+45 ) # inf

8. 分数运算

  • fractions

fractions 模块可以被用来执行包含分数的数学运算。

from fractions import Fraction

a = Fraction(5, 4)
print( a ) # 5/4
print( a.numerator, a.denominator) # 5 4
print( float(a) ) # 1.25

在大多数程序中一般不会出现分数的计算问题,但是有时候还是需要用到的。 比如,在一个允许接受分数形式的测试单位并以分数形式执行运算的程序中, 直接使用分数可以减少手动转换为小数或浮点数的工作。

猜你喜欢

转载自blog.csdn.net/shenziheng1/article/details/83471905
今日推荐