简体   繁体   English

用十进制换钱如何避免python中的浮点问题?

[英]How does using decimal for money avoid the floating point problems in python?

So currency/money has lot's of known math issues when using a floating point.因此,在使用浮点数时,货币/货币有很多已知的数学问题。 It seems in python that decimal is used in money libraries, but according to the python docs , decimal is based on a floating point.在 python 中,货币库中使用了decimal ,但根据python 文档decimal基于浮点数。 So how does this not have the same problems?那么这怎么没有同样的问题呢?

context a lot of currency libraries measure their monetary values as integers (so cents of USD, not dollars).上下文许多货币库以整数来衡量它们的货币价值(因此是美分,而不是美元)。 We've just had the issue of a python application representing it's money as decimal, it goes into javascript, which then needs to convert it to an integer for another service.我们刚刚遇到了一个 python 应用程序的问题,它用十进制表示它的钱,它进入 javascript,然后需要将它转换为另一个服务的整数。

10.05 / 100, became 1050.0000...1 which is of course, not an integer. 10.05 / 100,变成了 1050.0000...1 这当然不是整数。 So of course I was wondering why python chose this route, as most recommendations I've seen recommend treating money as integers.所以我当然想知道为什么 python 选择这条路线,因为我见过的大多数建议都建议将钱视为整数。

You are confusing binary floating point with decimal floating point.您将二进制浮点数与十进制浮点数混淆。 From the module documentation :模块文档

The decimal module provides support for fast correctly-rounded decimal floating point arithmetic.十进制模块为快速正确舍入的十进制浮点运算提供支持。

[...] [...]

  • Decimal numbers can be represented exactly.十进制数可以精确表示。 In contrast, numbers like 1.1 and 2.2 do not have exact representations in binary floating point相比之下,像 1.1 和 2.2 这样的数字在二进制浮点数中没有精确的表示

(bold emphasis mine). (粗体强调我的)。

The floating point aspect refers to the variability of the exponent;浮点方面是指指数的可变性; the number 12300000 can be represented as 123 with a decimal exponent of 5 (10 ** 5).数字12300000可以表示为 123,十进制指数为 5 (10 ** 5)。 Both float and decimal use a floating point representation. floatdecimal使用浮点数表示。 But float adds up a number of binary fractions (1/2 + 1/4 + 1/8 + 1/16 + ...), and that makes them unsuitable for representing currencies as binary fractions can not predicisely model 1/100ths or 1/10ths, which currency values tend to use a lot.但是float加起来了许多二进制分数(1/2 + 1/4 + 1/8 + 1/16 + ...),使得它们不适合表示货币,因为二进制分数不能精确地模拟 1/100 或1/10,这些货币价值往往使用很多。

The DZone article on floating point issues for currency you link also teaches you about the Java java.math.BigDecimal package .您链接的有关货币浮点问题DZone 文章还教您有关 Java java.math.BigDecimal包的知识 Python's decimal is essentially the same thing ; Python 的decimal本质上是一回事 where the BigDecimal documentation talks about values consist[ing] of an arbitrary precision integer unscaled value and a 32-bit integer scale , the scale is essentially the position of the floating point. BigDecimal文档讨论的值由 [ing] 任意精度整数未缩放值和 32 位整数 scale 组成,其中scale本质上是浮点的位置。

Because decimal can represent 1/100ths (cents) in currency values exactly, it is far more suitable to model currency values.因为decimal可以decimal地表示货币价值的 1/100(美分),所以它更适合对货币价值建模。

Decimal avoids some of the problems of binary floating-point, but not all, possibly not even most. Decimal 避免了二进制浮点的一些问题,但不是全部,甚至可能不是大部分。

The actual problem is not floating-point but numerical formats.实际问题不是浮点而是数字格式。 No numerical format can represent all real numbers, or even all rational numbers, so no numerical format can handle all the operations we want to do with numbers.没有数字格式可以表示所有实数,甚至所有有理数,因此没有数字格式可以处理我们想要对数字进行的所有操作。

Money is commonly represented in decimal fractions of a unit of currency.货币通常以货币单位的十进制小数表示。 For example, the US dollar and many other currencies have as a “cent” which is 1/100 th of a dollar.例如,美元和其他许多货币都有一个“分”,这是1/100美元。 A decimal format can represent 1/100 th exactly.十进制格式可以精确地表示1/100。 A binary format cannot.二进制格式不能。 So, with a decimal format, you can:因此,使用十进制格式,您可以:

  • Represent decimal units of currency exactly (within bounds of the format).准确表示货币的十进制单位(在格式范围内)。
  • Add and subtract decimal amounts of currency exactly (within bounds of the format).精确地添加和减去十进制货币数量(在格式范围内)。
  • Multiply decimal units of currency by integers exactly (within bounds of the format).将货币的十进制单位精确地乘以整数(在格式范围内)。

However, problems arise when you try:但是,当您尝试时会出现问题:

  • To average numbers or divide by numbers other than powers of ten (or two or five).平均数或除以十(或二或五的幂)以外的数字。 For example, if a grocery wants to sell a product at three for a dollar, there is no way to represent ⅓ exactly in a decimal format.例如,如果一家杂货店想以 3 美元的价格出售一种产品,则无法以十进制格式准确表示 ⅓。
  • Multiplying numbers with decimal fractions more than a few times.将数字与小数相乘多次。 Each multiplication will increase the number of digits after the decimal point.每次乘法都会增加小数点后的位数。 For example, interest compounded monthly for a year cannot be computed exactly with typical decimal formats.例如,不能用典型的十进制格式精确计算一年的每月复利。
  • Any complex (in the general sense, not mathematical) operations such as exponentiation that may be involved in considering the time value of money, stock market options evaluation, and so on.考虑货币时间价值、股票市场期权评估等可能涉及的任何复杂(一般意义上,非数学)运算,例如取幂。

There is no general solution to how to compute numerically.对于如何进行数值计算,没有通用的解决方案。 Studying numerical computing and its errors is an entire field of study with textbooks, courses, and research papers.研究数值计算及其错误是一个完整的研究领域,包括教科书、课程和研究论文。 So you cannot solve numerical problems merely by choosing a format.所以你不能仅仅通过选择一种格式来解决数值问题。 It is important to understand whatever format(s) you use, what errors arise in using them, how to deal with those errors, and what results you need to achieve.了解您使用的任何格式、使用它们时出现的错误、如何处理这些错误以及您需要达到的结果是很重要的。

Decimal types allow decimal floating point rather than binary floating point.十进制类型允许十进制浮点而不是二进制浮点。 The class of problems you are referring to relate to the latter.您所指的问题类别与后者有关。

声明:本站的技术帖子网页,遵循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 货币面额循环不适用于十进制 - Python money denomination loop does not work on decimal 如何设置浮点精度以避免Python中的浮点运算错误? - How can I set floating point precision to avoid floating point arithmetic error in Python? Python新手如何克服浮点比较的问题 - How a Python newbie might overcome problems with floating point comparisons 在Python中以十进制形式显示浮点数? - Display floating point number in decimal form in Python? 6是python格式浮点的默认十进制数字吗? - Is 6 the default decimal digits of floating point in python format? Python 的十进制(和其他精确的十进制库)是如何实现的,为什么它们比内置的浮点计算慢? - How is Python's decimal (and other precise decimal libraries) implemented and why are they slower than built in floating point calculations? 限制浮点值以避免python中的溢出 - Restricting floating point values to avoid overflow in python 如何在 Django 中将浮点数和小数相乘? - How to multiply a floating point number and a decimal in Django? Python 中浮点与十进制(定点)的规范 - Norms in Python for floating point vs. Decimal (fixed-point)
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM