Python十进制模块-不希望的浮点型输出?

Python十进制模块-不希望的浮点型输出?,python,floating-point,Python,Floating Point,我想这是非常简单的-但是为什么下面是ynot==0的两个值?我认为十进制模块的全部目的是消除浮尘…下面是一个数学例程的极其简化版本,它将数字作为变量传递 from decimal import * getcontext().prec = 2 q = Decimal(0.01) x = Decimal(0.10) * Decimal(0.10) y = Decimal(x) - Decimal(q) print(x,y, Decimal(y)) ''' x== 0.010 y== -

我想这是非常简单的-但是为什么下面是
y
not==0的两个值?我认为十进制模块的全部目的是消除浮尘…下面是一个数学例程的极其简化版本,它将数字作为变量传递

from decimal import * 
getcontext().prec = 2

q = Decimal(0.01)

x = Decimal(0.10) * Decimal(0.10)

y = Decimal(x) - Decimal(q)

print(x,y, Decimal(y))

'''
x== 0.010 
y== -2.1E-19 
Decimal(y) == -2.1E-19
'''

float
literal
0.10
并不是精确的数学数
0.10
,使用它来初始化
Decimal
并不能避免
float
精度问题

相反,使用字符串初始化
Decimal
可以得到预期的结果:

x = Decimal('0.10') * Decimal('0.10')
y = Decimal(x) - Decimal('0.010')

float
literal
0.10
并不是精确的数学数
0.10
,使用它来初始化
Decimal
并不能避免
float
精度问题

相反,使用字符串初始化
Decimal
可以得到预期的结果:

x = Decimal('0.10') * Decimal('0.10')
y = Decimal(x) - Decimal('0.010')

尝试将数字指定为字符串

>>> Decimal('0.10') * Decimal('0.10') - Decimal('0.0100')
>>> Decimal('0.000')

尝试将数字指定为字符串

>>> Decimal('0.10') * Decimal('0.10') - Decimal('0.0100')
>>> Decimal('0.000')

这是对现有答案中所述观点的更详细解释

如果需要精确的十进制算法,您确实需要去掉数值文本,例如
0.1
。数字文字通常由IEEE 754 64位二进制浮点数表示

与0.1最接近的数字为0.10000000000000055115123125782702118158340451015625。其平方为0.010000000001110223024625156571123851077828659613956470813588370960962637144621112383902072906494140625,与最接近的0.01、0.0100000000002081668171172168513294309377070288085975不一样

通过删除
prec=2
上下文,您可以更清楚地了解正在发生的事情,从而允许更精确的输出:

from decimal import * 
q = Decimal(0.01)
x = Decimal(0.10) * Decimal(0.10)
y = Decimal(x) - Decimal(q)
print(q)
print(x)
print(y)
输出:

0.01000000000000000020816681711721685132943093776702880859375
0.01000000000000000111022302463
9.020562075127831486705690622E-19

如果您使用了字符串文字,正如其他响应所建议的那样,那么将直接转换为十进制,而不需要经过二进制浮点运算。0.1和0.01都可以精确地用十进制表示,因此不会有舍入误差。

这是对现有答案中观点的更详细解释

如果需要精确的十进制算法,您确实需要去掉数值文本,例如
0.1
。数字文字通常由IEEE 754 64位二进制浮点数表示

与0.1最接近的数字为0.10000000000000055115123125782702118158340451015625。其平方为0.010000000001110223024625156571123851077828659613956470813588370960962637144621112383902072906494140625,与最接近的0.01、0.0100000000002081668171172168513294309377070288085975不一样

通过删除
prec=2
上下文,您可以更清楚地了解正在发生的事情,从而允许更精确的输出:

from decimal import * 
q = Decimal(0.01)
x = Decimal(0.10) * Decimal(0.10)
y = Decimal(x) - Decimal(q)
print(q)
print(x)
print(y)
输出:

0.01000000000000000020816681711721685132943093776702880859375
0.01000000000000000111022302463
9.020562075127831486705690622E-19

如果您使用了字符串文字,正如其他响应所建议的那样,那么将直接转换为十进制,而不需要经过二进制浮点运算。0.1和0.01都可以用十进制表示,因此不会有舍入错误。

嘿,谢谢,知道类似十进制的字符串很好,我根据你的回答编辑了一点问题,但是嘿,谢谢,知道类似十进制的字符串很好,我根据你的回答编辑了一点问题,但是谢谢,知道类似于十进制的字符串很好,我根据您的回答对问题进行了一些编辑,尽管不需要将
x
转换为
Decimal
,它已经是了。常用的小数算术运算符会产生小数结果。嘿,谢谢,知道类似小数的字符串很好,我根据您的回答对问题进行了一些编辑,虽然不需要将
x
转换为
Decimal
,它已经是了。常用的十进制算术运算符产生十进制结果。