十进制模块:舍入

时间:2013-08-26 14:33:23

标签: python decimal

我在获得所需的值时遇到了一些麻烦。

以下'abc'字符串表示角度。 'result'字符串代表我正在寻找的值。

a = '199.1224'
result = '199.122400000000000'

b = '199.0362'
result = '199.036200000000010'

c = '-199.9591'
result = '-199.959100000000010'

我使用以下代码:

Decimal(float(a)).quantize(Decimal('.000000000000001'), rounding=ROUND_HALF_UP)

results in 
a = 199.122399999999999
b = 199.036200000000008
c = -199.959100000000007

我不是数学天才,在十进制模块中尝试了几乎所有可能的东西,但我似乎无法找到正确的方法来获得我需要的结果。

作为一种糟糕的解决方法,我使用:

Decimal(float(a)).quantize(Decimal('.00000000000001'), rounding=ROUND_HALF_UP)
str(a)+'0'

所以使用少一个十进制进行量化,转换为字符串(无论如何必须这样做)并添加零。 这可以通过数千个这些值获得正确的预期结果。 但是我想知道是否有一个正确的方法来回合和结束零(不知道英语单词)。

2 个答案:

答案 0 :(得分:0)

我认为问题在于使用float(a)。 float类型没有大多数终止小数部分的精确表示。我用过:

from decimal import *
b = '199.0362'
Decimal(float(b)).quantize(Decimal('.000000000000001'), rounding=ROUND_HALF_UP)
Decimal(b).quantize(Decimal('.000000000000001'), rounding=ROUND_HALF_UP)

并获得Decimal('199.036200000000008'),就像你在第一个上所做的一样,但是Decimal('199.036200000000000')在第二个上。那么......为你做的float()转换是什么,你不能只使用第二个版本?

如果您需要从计算的浮点结果中获取输入,请记住您只获得大约52位的重要性,或大约52 * log10(2)~15.6的十进制数字。所以第16个重要数字可能没有正确地舍入为实际目的通常被认为是15。您可以使用格式函数在字符串中获得舍入结果:

format(float(b), ".15g")

这将抑制尾随小数零,并在更方便时切换到科学记数法。但它会将结果四舍五入到15位有效数字。您可能必须将其结果格式化为所需的固定小数位数:

d = Decimal(float(b), ".15g")
print ("d = " + format(d, ".12f"))

答案 1 :(得分:-1)

import decimal
from decimal import Decimal

b = '199.0362'
result = Decimal(float(b)).quantize(Decimal('0e-14'), rounding=decimal.ROUND_HALF_UP)
print format(result, '.15f')

# a:  '199.1224' ->  '199.122400000000000'
# b:  '199.0362' ->  '199.036200000000010'
# c: '-199.9591' -> '-199.959100000000010'
  • 如果您在'0e-14'中使用'0.00000000000001'而不是quantize,则无需计算数字以检查其是否正确。
  • 使用format函数转换为具有特定小数位数的字符串。