y.s*_*hyk 3 python floating-accuracy python-3.x
Python(以及几乎任何其他东西)在处理浮点数时都有已知的限制(这里提供了很好的概述)。
虽然文档中对问题进行了很好的描述,但它避免提供任何修复方法。有了这个问题,我正在寻求一种或多或少稳健的方法来避免以下情况:
print(math.floor(0.09/0.015)) # >> 6
print(math.floor(0.009/0.0015)) # >> 5
print(99.99-99.973) # >> 0.016999999999825377
print(.99-.973) # >> 0.017000000000000015
var = 0.009
step = 0.0015
print(var < math.floor(var/step)*step+step) # False
print(var < (math.floor(var/step)+1)*step) # True
Run Code Online (Sandbox Code Playgroud)
与此问题中建议的不同,他们的解决方案无助于解决诸如 next 代码随机失败之类的问题:
total_bins = math.ceil((data_max - data_min) / width) # round to upper
new_max = data_min + total_bins * width
assert new_max >= data_max
# fails. because for example 1.9459999999999997 < 1.946
Run Code Online (Sandbox Code Playgroud)
int。Sometimes people use float in places where they definitely shouldn't. If you're counting something (like number of cars in the world) as opposed to measuring something (like how much gasoline is used per day), floating-point is probably the wrong choice. Currency is another example where floating point numbers are often abused: if you're storing your bank account balance in a database, it's really not 123.45 dollars, it's 12345 cents. (But also see below about Decimal.)
float.Floating-point numbers are general-purpose. They're extremely accurate; they just can't represent certain fractions, like finite decimal numbers can't represent the number 1/3. Floats are generally suited for any kind of analog quantity where the measurement has error bars: length, mass, frequency, energy -- if there's uncertainty on the order of 2^(-52) or greater, there's probably no good reason not to use float.
float but format it."This number looks weird" is a bad reason not to use float. But that doesn't mean you have to display the number to arbitrary precision. If a number with only three significant figures comes out to 19.99909997918947, format it to one decimal place and be done with it.
>>> print('{:0.1f}'.format(e**pi - pi))
20.0
Run Code Online (Sandbox Code Playgroud)
Decimal.Sraw's answer refers to the decimal module, which is part of the standard library. I already mentioned currency as a discrete quantity, but you may need to do calculations on amounts of currency in which not all numbers are discrete, for example calculating interest. If you're writing code for an accounting system, there will be rules that say when rounding is applied and to what accuracy various calculations are done, and those specifications will be written in terms of decimal places. In this situation and others where the decimal representation is inherent to the problem specification, you'll want to use a decimal type.
>>> from decimal import Decimal
>>> rate = Decimal('0.0345')
>>> principal = Decimal('3412.65')
>>> interest = rate*principal
>>> interest
Decimal('117.736425')
>>> interest.quantize(Decimal('0.01'))
Decimal('117.74')
Run Code Online (Sandbox Code Playgroud)
Several of your examples use math.floor, which takes a float and chops off the fractional part. In any situation where you should use math.floor, floating-point error doesn't matter. (If you want to round to the nearest integer, use round instead.) Yes, there are ways to use floating-point operations that have wrong results from a mathematical standpoint. But real-world quantities usually fall into one of these categories:
float;As a programmer, it's part of your job to know the quantities you're dealing with and choose appropriate data types. So there's no "fix" for floating point numbers, because there's no "problem" really -- just people using the wrong type for the wrong thing.
让我们来谈谈decimal。实际上,这个库将数字转换为类似字符串的对象,然后基于字符进行任何算术运算。
因此在这种情况下,它可以以几乎完美的精度处理相当大的数字。
但是,由于它根据字符计算数字,因此成本要高得多。
此外,如果要使用decimal, 来确保精度,则需要始终如一地使用它。如果decimal与普通类型(例如 )混合使用float,可能会导致意想不到的问题。
最后,当你构造一个Decimal对象时,最好传递一个字符串而不是数字。
>>> print(Decimal(99.99) - Decimal(99.973))
0.01699999999999590727384202182
>>> print(Decimal("99.99") - Decimal("99.973"))
0.017
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3775 次 |
| 最近记录: |