简体   繁体   English

Python 的十进制(和其他精确的十进制库)是如何实现的,为什么它们比内置的浮点计算慢?

[英]How is Python's decimal (and other precise decimal libraries) implemented and why are they slower than built in floating point calculations?

I've been reading the floating point guide to try to clarify some points about floating point numbers and I assume Python's decimal library is an implementation of "Limited-Precision Decimal" mentioned on the linked page.我一直在阅读浮点指南以试图澄清有关浮点数的一些要点,我假设 Python 的十进制库是链接页面上提到的“有限精度十进制”的实现。

It mentions that "Limited-Precision Decimal" is "Basically the same as a IEEE 754 binary floating-point, except that the exponent is interpreted as base 10. As a result, there are no unexpected rounding errors. Also, this kind of format is relatively compact and fast, but usually slower than binary formats."它提到“Limited-Precision Decimal”“与 IEEE 754 二进制浮点基本相同,只是指数被解释为以 10 为底。因此,没有意外的舍入错误。此外,这种格式相对紧凑和快速,但通常比二进制格式慢。”

Is Python decimal implemented the same way? Python十进制是否以相同的方式实现? If all else is equal in the representation besides the exponent being interpreted differently, why is it slower and why isn't this representation always preferred over the IEEE 754 implementation?如果除了指数被不同地解释之外,表示中的所有其他内容都相同,为什么它更慢,为什么这种表示并不总是优于 IEEE 754 实现? Finally, why does using the exponent as base 10 prevent unexpected rounding errors?最后,为什么使用以 10 为底的指数可以防止意外的舍入错误?

Thanks!谢谢!

It mentions that "Limited-Precision Decimal" [...] Is Python decimal implemented the same way?它提到“有限精度十进制”[...] Python 十进制是否以相同的方式实现?

No, internally Python's Decimal uses a base-10 exponent, along with an arbitrarily large integer.不,Python 的 Decimal 内部使用以 10 为底的指数,以及任意大的 integer。 Since the size of the integer is unlimited, the potential precision is unlimited too.由于 integer 的尺寸是无限的,潜在的精度也是无限的。

why is [Python's Decimal] slower为什么 [Python's Decimal] 较慢

There are a few reasons for this.这有几个原因。 First, adding two Decimal values of different exponents requires multiplying by ten, and multiplying by ten is more expensive than multiplying by two on a computer which uses binary.首先,将两个不同指数的 Decimal 值相加需要乘以 10,在使用二进制的计算机上,乘以 10 比乘以 2 更昂贵。 Second, doing an exact calculation requires more digits of precision than doing an approximate calculation.其次,进行精确计算比进行近似计算需要更多位数的精度。 Third, IEEE754 floating point has hardware acceleration because it's such a common operation.第三,IEEE754浮点具有硬件加速,因为它是一种常见的操作。

why isn't this representation always preferred over the IEEE 754 implementation?为什么这种表示并不总是优于 IEEE 754 实现?

Speed is a feature, and not all calculations benefit from being done exactly.速度是一个特征,并不是所有的计算都能从精确完成中受益。 The use of inexact calculations is more widespread than you might think.不精确计算的使用比您想象的要广泛。 For example, Excel uses floating-point numbers internally .例如,Excel 在内部使用浮点数 Yet, it has hundreds of millions of users, so evidently you can get pretty far with only floating point.然而,它有数亿用户,所以显然你可以只使用浮点数。

Finally, why does using the exponent as base 10 prevent unexpected rounding errors?最后,为什么使用以 10 为底的指数可以防止意外的舍入错误?

The key word in that sentence is "unexpected."这句话的关键词是“出乎意料”。 You wouldn't be surprised to learn that a base 10 number system can't represent the number 1/3 without rounding it.得知以 10 为底的数字系统无法表示数字 1/3 而不对其进行四舍五入,您不会感到惊讶。 We understand and are okay with not being able to represent 1/3, 1/7, and 1/9 perfectly accurately.我们理解并且不能完全准确地表示 1/3、1/7 和 1/9。 But people are much less accepting of computer systems which can't represent 1/5 accurately.但是人们对不能准确表示 1/5 的计算机系统的接受程度要低得多。

If you tried to represent 0.2 in binary, you'd get 0.0011(0011), with the 0011 part repeating forever.如果你试图用二进制表示 0.2,你会得到 0.0011(0011),其中 0011 部分永远重复。 A floating point number doesn't have an infinite number of bits, so it rounds off everything after 53 bits (assuming double precision) and approximates it.浮点数没有无限位数,因此它会在 53 位之后四舍五入(假设为双精度)并对其进行近似。

This is not to say that Decimal is perfectly accurate.这并不是说 Decimal 是完全准确的。 There are lots of situations that force rounding.有很多情况会强制舍入。 For example, if you took the square root of two, that's an irrational number, and can't be represented as an exact decimal.例如,如果你取 2 的平方根,这是一个无理数,不能表示为精确的小数。

Example:例子:

>>> Decimal(2).sqrt()
Decimal('1.414213562373095048801688724')
>>> Decimal(2).sqrt() ** 2
Decimal('1.999999999999999999999999999')

Decimal is a way of doing math that agrees with the answer you'd get by doing it with pencil and paper.十进制是一种数学运算方法,它与您用铅笔和纸做的答案一致。 For this, it trades off speed and memory use.为此,它权衡了速度和 memory 的使用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在不使用小数、分数或任何其他外部库的情况下修复浮点数中的 Python 舍入错误? - How to fix Python rounding error in Floating Point numbers without using decimal, fractions or any other external libraries? 用十进制换钱如何避免python中的浮点问题? - How does using decimal for money avoid the floating point problems in python? 在Python中以十进制形式显示浮点数? - Display floating point number in decimal form in Python? 6是python格式浮点的默认十进制数字吗? - Is 6 the default decimal digits of floating point in python format? 如何在 Django 中将浮点数和小数相乘? - How to multiply a floating point number and a decimal in Django? 获取 Python Decimal 的精确十进制字符串表示? - Get precise decimal string representation of Python Decimal? 没有 Decimal.quantize 的快速和精确的最近步浮点天花板/地板 - Fast and precise nearest step floating point ceiling/flooring without Decimal.quantize Python 中浮点与十进制(定点)的规范 - Norms in Python for floating point vs. Decimal (fixed-point) 主机S370十六进制浮点数转换为十进制 - Conversion of mainframe S370 hexadecimal floating–point to decimal 如何在Python中制作numpy.pow的精确小数 - How to make precise decimal of numpy.pow in Python
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM