我要把一个很长的数分成更小的数。两者都是十进制类型。小数((。
结果是用科学的符号表示出来的。我该如何阻止这种情况?我需要打印完整的数字。
>>> decimal.getcontext().prec
50
>>> val
Decimal('1000000000000000000000000')
>>> units
Decimal('1500000000')
>>> units / val
Decimal('1.5E-15')
精度在内部保持-您只需要在将十进制值导出为字符串时显式调用所需的小数位数。
因此,如果要打印或在HTML模板中插入值,第一步是使用字符串格式方法(或f-string(,以确保包含数字:
In [29]: print(f"{units/val:.50f}")
0.00000000000000150000000000000000000000000000000000
不幸的是,字符串格式的迷你语言本身无法消除右侧多余的零。(左侧可以填充"0"、"、自定义字符,无论需要什么,但小数分隔符后的所有精度都转换为尾随的0(。
由于找到最低有效的非零数字是复杂的——换句话说,我们可以使用从数字中提取的参数,而不是"0";50〃;为了提高格式表达式的精度,更简单的方法是在格式化后使用字符串.rstrip
方法删除这些零:
In [30]: print(f"{units/val:.50f}".rstrip("0"))
0.0000000000000015
简言之:这似乎是唯一的方法:在所有接口点中,当数字将核心留给一个输出时,它被表示为字符串,你可以用定点表示法对其进行超精度格式化,并用f-string去掉尾部的零:
return template.render(number=f"{number:.50f}".rstrip("0"), ...)
使用浮点型指示符{:,f}
将小数呈现为格式化字符串,它将显示正确的位数来表示整数,无论它是非常大的整数还是非常大的小数。
>>> val
Decimal('1000000000000000000000000')
>>> units
Decimal('1500000000')
>>> "{:,f}".format(units / val)
'0.0000000000000015'
# very large decimal integer, formatted as float-type string, appears without any decimal places at all when it has none! Nice!
>>> "{:,f}".format(units * val)
'1,500,000,000,000,000,000,000,000,000,000,000'
您不需要指定小数位数。它将只显示表示数字所需的数量,当小数小于固定格式宽度时,省略最后一个小数位数后出现的无用零的踪迹。如果这个数字没有小数部分,你就不会得到任何小数点。
因此,可以容纳非常大的数字,而无需猜测它们的大小。您也不必猜测它们是否有小数点。
任何指定的千位分隔符{:,f}
同样只有在数字是大整数而不是长小数时才有效。
Proviso
然而,Decimal((具有有效位的想法,如果它认为您需要,它将添加尾随零。
这个想法是,它可以智能地处理您可能正在处理货币数字(如£ 10.15
(的情况。使用文档中的示例:
>>> decimal.Decimal('1.30') + decimal.Decimal('1.20')
Decimal('2.50')
如果你格式化Decimal((,这没有什么区别——如果Decimal(认为它很重要,你仍然会得到尾随的零:
>>> "{:,f}".format( decimal.Decimal('1.30') + decimal.Decimal('1.20'))
'2.50'
当你把成千上万的分数放在一起处理时,也会发生同样的事情(也许有充分的理由?(:
>>> decimal.Decimal(2500) * decimal.Decimal('0.001')
Decimal('2.500')
使用Decimal((.normalize((方法删除有效的尾随零:
>>> (2500 * decimal.Decimal('0.001')).normalize()
Decimal('2.5')