为了使它起作用,您必须先对小数进行归一化:
>>> x = decimal.Decimal ('10000000')>>> x.normalize()Decimal('1E+7')>>> x.normalize().to_eng_string()'10E+6'可以通过深入研究源代码来发现其原因。
如果您检查
to_eng_string()在Python
2.7.3源代码树(
Lib/decimal.py从gzip压缩的源焦油球在这里),它只是简单地调用
__str__与
eng设置为true。
然后,您可以看到它决定了最初使用十进制小数点左边的位数:
leftdigits = self._exp + len(self._int)
下表显示了这两件事的值:
._exp ._int len leftdigits ----- --------- --- ----------Decimal (1000000) 0 '1000000' 7 7Decimal ('1E+6') 6 '1' 1 7此后继续的代码是:
if self._exp <= 0 and leftdigits > -6: # no exponent required dotplace = leftdigitselif not eng: # usual scientific notation: 1 digit on left of the point dotplace = 1elif self._int == '0': # engineering notation, zero dotplace = (leftdigits + 1) % 3 - 1else: # engineering notation, nonzero dotplace = (leftdigits - 1) % 3 + 1
并且您会看到,除非它已经 具有 一定范围内的指数(
self._exp > 0 or leftdigits <=-6),否则在字符串表示形式中将不会给出任何指数。
进一步的调查显示了这种行为的原因。查看代码本身,您将看到它基于
General Decimal ArithmeticSpecification(此处的PDF
)。
如果您搜索该文档
to-scientific-string(基于文档
to-engineering-string),则部分说明(措辞并加粗体):
如果需要指数 ,“ to-scientific-string”操作会将数字转换为字符串,并使用科学计数法 。 该操作不受上下文的影响。
如果该数字是有限数,则:
该系数首先使用从0到9的字符转换为以10为底的字符串,且不带前导零(除非其值为零,在这种情况下使用单个0字符)。
接下来,计算调整后的指数。这是指数,加上转换系数中的字符数,再减去一个。也就是说,指数+(clength-1),其中clength是系数的长度(以十进制数字表示)。
如果指数小于或等于零,并且调整后的指数大于或等于-6,则数字将转换为字符形式而无需使用指数表示法。
在这种情况下,如果指数为零,则不添加小数点。否则(指数为负),将插入一个小数点,该指数的绝对值指定小数点右边的字符数。必要时,将“
0”字符添加到转换系数的左侧。如果在插入后小数点之前没有字符,则以常规的“ 0”字符为前缀。
换句话说,它正在做它正在做的事情,因为这就是标准告诉它要做的事情。



