我正在尝试使用python将数字打印成工程格式,但似乎无法正常工作。SEEMS语法很简单,但是却行不通。
>>> import decimal >>> x = decimal.Decimal(1000000) >>> print x 1000000 >>>> print x.to_eng_string() 1000000
我不知道为什么会这样。这两个值不相等(一个是字符串,另一个是int)。设置各种上下文decimal似乎也无济于事。有任何线索或想法吗?
decimal
为了使它起作用,您必须先对小数进行归一化:
>>> 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。
to_eng_string()
Lib/decimal.py
__str__
eng
然后,您可以看到它决定了最初使用十进制小数点左边的位数:
leftdigits = self._exp + len(self._int)
下表显示了这两件事的值:
._exp ._int len leftdigits ----- --------- --- ---------- Decimal (1000000) 0 '1000000' 7 7 Decimal ('1E+6') 6 '1' 1 7
此后继续的代码是:
if self._exp <= 0 and leftdigits > -6: # no exponent required dotplace = leftdigits elif not eng: # usual scientific notation: 1 digit on left of the point dotplace = 1 elif self._int == '0': # engineering notation, zero dotplace = (leftdigits + 1) % 3 - 1 else: # engineering notation, nonzero dotplace = (leftdigits - 1) % 3 + 1
并且您会看到,除非它已经 具有 一定范围内的指数(self._exp > 0 or leftdigits <= -6),否则在字符串表示形式中将不会给出任何指数。
self._exp > 0 or leftdigits <= -6
进一步的调查显示了这种行为的原因。查看代码本身,您将看到它基于General Decimal Arithmetic Specification(此处的PDF )。
General Decimal Arithmetic Specification
如果您搜索该文档to-scientific-string(基于文档to-engineering-string),则部分说明(措辞并加粗体):
to-scientific-string
to-engineering-string
如果需要指数 ,“ to-scientific-string”操作会将数字转换为字符串,并使用科学计数法 。 该操作不受上下文的影响。 如果该数字是有限数,则: 该系数首先使用从0到9的字符转换为以10为底的字符串,且不带前导零(除非其值为零,在这种情况下使用单个0字符)。 接下来,计算调整后的指数。这是指数,加上转换系数中的字符数,再减去一个。也就是说,指数+(clength-1),其中clength是系数的长度(以十进制数字表示)。 如果指数小于或等于零,并且调整后的指数大于或等于-6,则数字将转换为字符形式而无需使用指数表示法。 在这种情况下,如果指数为零,则不添加小数点。否则(指数为负),将插入一个小数点,该指数的绝对值指定小数点右边的字符数。必要时,将“ 0”字符添加到转换系数的左侧。如果在插入后小数点之前没有字符,则以常规的“ 0”字符为前缀。
如果需要指数 ,“ to-scientific-string”操作会将数字转换为字符串,并使用科学计数法 。 该操作不受上下文的影响。
如果该数字是有限数,则:
该系数首先使用从0到9的字符转换为以10为底的字符串,且不带前导零(除非其值为零,在这种情况下使用单个0字符)。
接下来,计算调整后的指数。这是指数,加上转换系数中的字符数,再减去一个。也就是说,指数+(clength-1),其中clength是系数的长度(以十进制数字表示)。
如果指数小于或等于零,并且调整后的指数大于或等于-6,则数字将转换为字符形式而无需使用指数表示法。 在这种情况下,如果指数为零,则不添加小数点。否则(指数为负),将插入一个小数点,该指数的绝对值指定小数点右边的字符数。必要时,将“ 0”字符添加到转换系数的左侧。如果在插入后小数点之前没有字符,则以常规的“ 0”字符为前缀。
换句话说,它正在做它正在做的事情,因为这就是标准告诉它要做的事情。