【问题标题】:How to set precision without rounding?如何在不四舍五入的情况下设置精度?
【发布时间】:2014-06-02 12:30:14
【问题描述】:

我在数据库中有大整数 (numeric(24,0))。我想将此数字转换为“人类可读”格式。我有功能:

def from_int(value, precision):
    fprec = "%." + str(precision) + "f"
    return fprec % (Decimal(value) * (Decimal(10)**(-1*precision)))

它有效:

from_int(1000000, 6)
'1.000000'
from_int(1000000, 8)
'0.01000000'
from_int(1000000, 12)
'0.000001000000'
from_int(1000000, 2)
'10000.00'

但对于:

from_int(19999999999999999, 2)
'200000000000000.00'

如何在不四舍五入的情况下设置精度?

【问题讨论】:

  • 我认为您使用 precision 错误。更像是numberOfDecimalPlaces 之类的。

标签: python


【解决方案1】:

使用%f 格式化会将数字转换为失去精度的浮点数。而是使用str:

def from_int(value, precision):
    return str(Decimal(value) * Decimal(10)**(-precision))

【讨论】:

    【解决方案2】:

    问题出在需要浮点数的 %f 构造中。因此,即使您以十进制计算所有内容,最后也会出现令人讨厌的浮点转换 => 所以舍入问题。我想你可以写:

    def from_int(value, precision):
        return str((Decimal(value) * (Decimal(10)**(-1*precision))))
    

    我根据你的价值观对其进行了测试,它给出了正确的结果。

    【讨论】:

      【解决方案3】:

      如果你想要的只是一个字符串表示,你可以用这样的方式逃脱:

      >>> ('%%.%df' % 2) % 2.445
      '2.44'
      

      所以在您的原始代码中:

      def from_int(value, precision):
          return ('%%.%df' % precision) % value
      

      编辑:

      为了处理精度问题,使用Decimal 类型和quantize 方法确实更简单:

      >>> d = decimal.Decimal(19999999999999999)
      >>> prec = 2
      >>> str(d.quantize(decimal.Decimal(10) ** -prec))
      '19999999999999999.00'
      >>> 
      

      参考:How can I format a decimal to always show 2 decimal places?

      编辑:使用Decimal 类型,您可以在不四舍五入的情况下移动小数位:

      >>> str(d * (decimal.Decimal(10) ** -prec))
      '199999999999999.99'
      

      【讨论】:

      • 是的,但我想得到 199999999999999.99,而不是 199999999999999999.00
      • @Nips:已编辑以添加该部分。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-08-01
      • 1970-01-01
      • 2015-11-07
      • 2015-01-06
      • 1970-01-01
      • 1970-01-01
      • 2013-07-22
      相关资源
      最近更新 更多