为什么%e在格式字符串中的行为与%g不同?

时间:2015-06-01 18:20:16

标签: python c format-specifiers

我在Python2,Python3和C中试过这个:

为什么这些格式字符串会返回不同精度的数字?

>>> "%.3e" % 123456789
'1.235e+08' 
>>> "%.3g" % 123456789
'1.23e+08' 

3 个答案:

答案 0 :(得分:6)

来自python文档:

  

'e'指数表示法。使用字母“e”以科学记数法打印数字以表示指数。默认精度为6.

  

'G'
  一般格式。对于给定的精度p> = 1,这将数字四舍五入为p位有效数字,然后根据其大小以定点格式或科学计数法格式化结果。

     

精确的规则如下:假设使用表示类型“e”和精度p-1格式化的结果将具有指数exp。然后,如果-4< = exp< p,数字格式为表示类型'f'和精度p-1-exp。否则,使用表示类型“e”和精度p-1格式化数字。在这两种情况下,从有效数字中删除无关紧要的尾随零,如果后面没有剩余数字,则也会删除小数点。

     

无论精度如何,正负无穷大,正负零和nans分别被格式化为inf,-inf,0,-0和nan。

     

精度0被视为等于1的精度。默认精度为6.

使用替代值:

>>> "%.3e" % 123
'1.230e+02'
>>> "%.3g" % 123
'123'
>>> "%.3e" % 1234
'1.234e+03'
>>> "%.3g" % 1234
'1.23e+03'

然后,差异显然在于如何指定精度。 g似乎使用精度作为精度的正常定义,而e使用小数点后的数字

答案 1 :(得分:2)

来自printf(3) man page

  

e,E

     

双参数是四舍五入的,并以[ - ] d.ddde±dd格式转换,其中小数点字符前面有一位数字,后面的位数等于精度;如果精度丢失,则取6;如果精度为零,则不显示小数点字符。 E转换使用字母E(而不是e)来引入指数。指数始终包含至少两位数;如果值为零,则指数为00.

     

...

     

g,G

     

双参数以样式f或e(或G或E转换为G转换)转换。 精度指定有效位数。如果精度丢失,则给出6位数字;如果精度为零,则将其视为1.如果转换的指数小于-4或大于或等于精度,则使用样式e。尾随零从结果的小数部分中删除;只有在后跟至少一位数字时才会出现小数点。

因此,即使具有相同的精确度,他们也会做不同的事情。

答案 2 :(得分:1)

我将首先描述%g的规则。

我发现@Dale Myers引用的文档已经非常详细地说明了这一点,我建议您看一下,但在此我将给出更清晰的解释。

指数和精度

在开始讨论规则之前,让我们先弄清楚exp(科学记数法中使用的指数)和precision(将简称为p ,它是格式表达式%.6e%.6g中使用的精度。精度默认为6)。

通用格式规则

好的,这是%g(通用格式)的规则:

  • -4 <= exp < p:使用十进制格式
  • exp < -4:使用指数格式
  • exp >= p:使用指数格式
  • 计算精度位数时,结果将四舍五入。
  • 精度用于限制所有数字,而不仅限于十进制数字。

让我们看看下面的所有极端情况:

>>> gx = '%.6g'
>>> ex = '%.6e'
# -4 <= exp < p
>>> gx % 12345
12345
>>> gx % 0.012345
0.012345
# exp == p
>>> ex % 1234567
1.23456e+06
>>> gx % 1234567
1.23457e+06 # Notic the decimal digits are rounded
# exp == -4
>>> ex % 0.000123456
1.234560e-4
>>> gx % 0.000123456
0.000123456
# exp < -4
>>> ex % 0.0000123456
1.234560e-5
>>> gx % 0.0000123456
1.23456e-5

为什么我们需要%g

如果您现在了解%g的规则,那么很显然,它会尝试在%fe之间找到中间立场,以便在格式化数字时将使用最适合您的格式,而不是您自己决定%f%e