【问题标题】:Rounding Decimal to configurable decimal places in python在python中将小数四舍五入到可配置的小数位
【发布时间】:2014-10-06 18:00:37
【问题描述】:

有没有比我在 Python 中舍入小数的方式更好(更快、更高效或“更 Pythonic”)的方式?我想出了以下几点:

sign, digits, exponent = the_number.as_tuple()
Decimal((sign, digits[:exponent+len(digits)+decimal_places],-decimal_places))

编辑: 我最终使用了另一种更快的解决方案[1],并且还将小数“填充”到所需的精度:

decimal.Decimal('%.*f' % (decimal_places, number))

[1] 速度快到小数点后 200 位。在我的情况下,我得到一个随机浮点值,我想将其“转换”为十进制,因此原始精度已经受到限制并且

【问题讨论】:

  • 你不只是四舍五入;您的代码更改了小数点的值。那是你要的吗?例如,如果decimal_places = 5,则the_number = Decimal('1000') 变为Decimal('0.01000')
  • 不,这不是故意的,而是完全错误的。我没有考虑整数小数,因为它们永远不会出现在我的代码中。但我的代码仍然是错误的,为了安全起见,我不会使用它;)
  • 您想四舍五入到特定的指数(例如,到最接近的十分位,或到小数点后的某些位数),还是要四舍五入到特定数量的有效数字?

标签: python-2.7 decimal rounding


【解决方案1】:

round(内置)呢:

>>> the_number = decimal.Decimal(1.23456789)
>>> round(the_number, 2)
Decimal('1.23')
>>> d=decimal.Decimal("31.100")
>>> d
Decimal('31.100')
>>> round(d, 10)
Decimal('31.1000000000')
>>> round(d, 20)
Decimal('31.10000000000000000000')
>>> round(d, 24)
Decimal('31.100000000000000000000000')
>>> round(d, 26)
Decimal('31.10000000000000000000000000')
>>> round(d, 1)
Decimal('31.1')
>>> round(d, 0)
Decimal('31')

【讨论】:

  • 使用 round(n,decimal_places) 和 n = Decimal(31.100) 总是返回 Decimal("31.1") 无论 decimal_places 的值,尽管 n 是 Decimal('31.10000000000000142108547152020037174224853515625')
  • 使用浮点数而不是字符串进行构造,即 Decimal(31.100) 而不是 Decimal('31.100'),它“不起作用”。如果您打印小数点,则显示用于 cunstruction 的浮点数的所有小数位。四舍五入时,“预期的”小数会神奇地恢复 - 它是如何工作的?我将不得不调查源头。同时,您的回答似乎是正确的,我只是不明白 round() 的魔力;)
  • 我现在接受了你的回答,因为它比来自 user3666197 的回答快得多,并且仍然可以做到。
【解决方案2】:

可以试试:

with decimal.localcontext() as ctx:
    ctx.prec = aWantedPRECISION          # temporarily adapt precision to aWantedPRECISION
    result   = +the_number               # set

如果这是 Pythonic-enough

【讨论】:

  • 太棒了!我虽然想在本地改变精度,但没有想出像你这样的好解决方案。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-06-24
  • 1970-01-01
  • 2012-11-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多