我是靠谱客的博主 能干长颈鹿,最近开发中收集的这篇文章主要介绍python浮点数类型与数学_Python3标准库:decimal定点数和浮点数的数学运算,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

1. decimal定点数和浮点数的数学运算

decimal模块实现了定点和浮点算术运算,使用的是大多数人所熟悉的模型,而不是程序员熟悉的模式(即大多数计算机硬件实现的IEEE浮点数运算)。Decimal实例可以准确的表示如何数,对其上火其下取整,还可以限制有效数字的个数。

1.1 Decimal

小数值被表示为Decimal类的实例。构造函数取一个整数或字符串作为参数。在使用浮点数创建Decimal之前,可以先将浮点数转换为一个字符串,以使调用者能够显式的处理值的位数,因为如果使用硬件浮点数表示则可能无法准确的表述。或者,类方法from_float()可以把浮点数转换为精确的小数表示。

importdecimal

fmt= '{0:<25} {1:<25}'

print(fmt.format('Input', 'Output'))print(fmt.format('-' * 25, '-' * 25))#Integer

print(fmt.format(5, decimal.Decimal(5)))#String

print(fmt.format('3.14', decimal.Decimal('3.14')))#Float

f = 0.1

print(fmt.format(repr(f), decimal.Decimal(str(f))))print('{:<0.23g} {:<25}'.format(

f,

str(decimal.Decimal.from_float(f))[:25])

)

浮点值0.1并没有被表示为一个精确的二进制值,所以float的表示与Decimal值不同。在这个输出的最后一行,完整的字符串表示被截断为25个字符。

1823516-20200229201147462-1344926195.png

Decimal还可以由元组创建,其中包含一个符号标志(0表示正,1表示负)、由数位组成的一个tuple以及一个整数指数。

importdecimal#Tuple

t = (1, (1, 1), -2)print('Input :', t)print('Decimal:', decimal.Decimal(t))

基于元组的表示在创建时不太方便,不过它提供了一种可移植的方式,这样可以导出小数值而不损失精度。元组形式可以通过网络传输,或者在不支持精确小数值的数据库中存储,以后再转换回Decimal实例。

1823516-20200229201521354-1773472657.png

1.2 格式化

Decimal对应Python的字符串格式化协议,使用与其他数值类型一样的语法和选项。

importdecimal

d= decimal.Decimal(1.1)print('Precision:')print('{:.1}'.format(d))print('{:.2}'.format(d))print('{:.3}'.format(d))print('{:.18}'.format(d))print('nWidth and precision combined:')print('{:5.1f} {:5.1g}'.format(d, d))print('{:5.2f} {:5.2g}'.format(d, d))print('{:5.2f} {:5.2g}'.format(d, d))print('nZero padding:')print('{:05.1}'.format(d))print('{:05.2}'.format(d))print('{:05.3}'.format(d))

格式字符串可以控制输出的宽度,精度(即有效数字个数),以及其填充值以占满宽度的方式。

1823516-20200229202155022-432792550.png

1.3 算术运算

Decimal重载了简单的算术操作符,所以可以采用与内置数值类型相同的方式来处理Decimal实例。

importdecimal

a= decimal.Decimal('5.1')

b= decimal.Decimal('3.14')

c= 4d= 3.14

print('a =', repr(a))print('b =', repr(b))print('c =', repr(c))print('d =', repr(d))print()print('a + b =', a +b)print('a - b =', a -b)print('a * b =', a *b)print('a / b =', a /b)print()print('a + c =', a +c)print('a - c =', a -c)print('a * c =', a *c)print('a / c =', a /c)print()print('a + d =', end=' ')try:print(a +d)exceptTypeError as e:print(e)

Decimal操作符还接受整数参数,不过,在这些操作符使用浮点值之前必须把浮点值转换为Decimal实例。

1823516-20200229202544234-1375165135.png

除了基本算术运算,Decimal还包括一些方法来查找以10为底的对数和自然对数。log10()和ln()返回的值都是Decimal实例,所以可以与其他值一样在公式中直接使用。

1.4 特殊值

除了期望的数字值,Decimal还可以表示很多特殊值,包括正负无穷大值、“不是一个数”(NaN)和0。

importdecimalfor value in ['Infinity', 'NaN', '0']:print(decimal.Decimal(value), decimal.Decimal('-' +value))print()#Math with infinity

print('Infinity + 1:', (decimal.Decimal('Infinity') + 1))print('-Infinity + 1:', (decimal.Decimal('-Infinity') + 1))#Print comparing NaN

print(decimal.Decimal('NaN') == decimal.Decimal('Infinity'))print(decimal.Decimal('NaN') != decimal.Decimal(1))

与无穷大值相加会返回另一个无穷大值。与NaN比较相等性总会返回false,而比较不等性总会返回true。与NaN比较大小来确定排序顺序是未定义的,这会导致一个错误。

1823516-20200229202959741-2068188659.png

1.5 上下文

到目前为止,前面的所有例子使用的都是decimal模块的默认行为。还可以使用一个上下文(context)来覆盖某些设置,如保持的精度、如何完成取整、错误处理等。上下文可以应用于一个线程中的所有Decimal实例,或者在一个小代码区中本地应用。

1.5.1 当前上下文

要获取当前全局上下文,可以使用getcontext()。

importdecimal

context=decimal.getcontext()print('Emax =', context.Emax)print('Emin =', context.Emin)print('capitals =', context.capitals)print('prec =', context.prec)print('rounding =', context.rounding)print('flags =')for f, v incontext.flags.items():print('{}: {}'.format(f, v))print('traps =')for t, v incontext.traps.items():print('{}: {}'.format(t, v))

这个示例脚本显示了Context的公共属性。

1823516-20200229203601834-350476750.png

1.5.2 精度

上下文的prec属性控制了作为算术运算结果创建的新值所要保持的精度。字面量值会按这个属性保持精度。

importdecimal

d= decimal.Decimal('0.123456')for i in range(1, 5):

decimal.getcontext().prec=iprint(i, ':', d, d * 1)

要改变精度,可以直接为这个属性赋一个1到decimal.MAX_PREC之间的新值。

1823516-20200229203903997-370189219.png

1.5.3 取整

取整有多种选择,以保证值在所需的精度范围内。

ROUND_CEILING:总是趋向无穷大向上取整。

ROUND_DOWN:总是趋向0取整。

ROUND_FLOOR:总是趋向负无穷大向下取整。

ROUND_HALF_DOWN:如果最后一个有效数字大于或大于5则朝0反方向取整;负责,趋向0取整。

ROUND_HALF_EVEN:类似于ROUND_HALF_DOWN,不过,如果最后一个有效数字为5,则会检查前一位。偶数值会导致结果向下取整,奇数值导致结果向上取整。

ROUND_HALF_UP:类似于ROUND_HALF_DOWN,不过如果最后一位有效数字为5,则值会朝0的反方向取整。

ROUND_UP:朝0的反方向取整。

ROUND_05UP:如果最后一位是0或5,则朝0的反方向取整;否则向0取整。

importdecimal

context=decimal.getcontext()

ROUNDING_MODES=['ROUND_CEILING','ROUND_DOWN','ROUND_FLOOR','ROUND_HALF_DOWN','ROUND_HALF_EVEN','ROUND_HALF_UP','ROUND_UP','ROUND_05UP',

]

header_fmt= '{:10}' + ' '.join(['{:^8}'] * 6)print(header_fmt.format(' ','1/8 (1)', '-1/8 (1)','1/8 (2)', '-1/8 (2)','1/8 (3)', '-1/8 (3)',

))for rounding_mode inROUNDING_MODES:print('{0:10}'.format(rounding_mode.partition('_')[-1]),

end=' ')for precision in [1, 2, 3]:

context.prec=precision

context.rounding=getattr(decimal, rounding_mode)

value= decimal.Decimal(1) / decimal.Decimal(8)print('{0:^8}'.format(value), end=' ')

value= decimal.Decimal(-1) / decimal.Decimal(8)print('{0:^8}'.format(value), end=' ')print()

这个程序显示了使用不同算法将同一个值取整为不同精度的效果。

1823516-20200229204805641-705215057.png

1.5.4 本地上下文

可以使用with语句对一个代码块应用上下文。

importdecimal

with decimal.localcontext() as c:

c.prec= 2

print('Local precision:', c.prec)print('3.14 / 3 =', (decimal.Decimal('3.14') / 3))print()print('Default precision:', decimal.getcontext().prec)print('3.14 / 3 =', (decimal.Decimal('3.14') / 3))

Context支持with使用的上下文管理器API,所以这个设置只在块内应用。

1823516-20200229204939239-138727391.png

1.5.5 各实例的上下文

还可以用上下文构造Decimal实例,然后从这个上下文继承精度以及转换的取整参数。

importdecimal#Set up a context with limited precision

c =decimal.getcontext().copy()

c.prec= 3

#Create our constant

pi = c.create_decimal('3.1415')#The constant value is rounded off

print('PI :', pi)#The result of using the constant uses the global context

print('RESULT:', decimal.Decimal('2.01') * pi)

例如,这样一来,应用就可以选择与用户数据精度不同的常用值精度。

1823516-20200229205158934-1146325559.png

1.5.6 线程

“全局”上下文实例上是线程本地上下文,所以完全可以使用不同的值分别配置各个线程。

importdecimalimportthreadingfrom queue importPriorityQueueclassMultiplier(threading.Thread):def __init__(self, a, b, prec, q):

self.a=a

self.b=b

self.prec=prec

self.q=q

threading.Thread.__init__(self)defrun(self):

c=decimal.getcontext().copy()

c.prec=self.prec

decimal.setcontext(c)

self.q.put((self.prec, a*b))

a= decimal.Decimal('3.14')

b= decimal.Decimal('1.234')#A PriorityQueue will return values sorted by precision,#no matter what order the threads finish.

q =PriorityQueue()

threads= [Multiplier(a, b, i, q) for i in range(1, 6)]for t inthreads:

t.start()for t inthreads:

t.join()for i in range(5):

prec, value=q.get()print('{} {}'.format(prec, value))

这个例子使用指定的值来创建一个新的上下文,然后安装到每个线程中。

1823516-20200229205415644-1048273102.png

最后

以上就是能干长颈鹿为你收集整理的python浮点数类型与数学_Python3标准库:decimal定点数和浮点数的数学运算的全部内容,希望文章能够帮你解决python浮点数类型与数学_Python3标准库:decimal定点数和浮点数的数学运算所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(47)

评论列表共有 0 条评论

立即
投稿
返回
顶部