【问题标题】:Why does %e behave different than %g in format strings?为什么 %e 在格式字符串中的行为与 %g 不同?
【发布时间】:2015-06-01 18:20:15
【问题描述】:

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

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

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

【问题讨论】:

  • 因为它们不同?看了答案后,我很困惑为什么 OP 认为两种不同的格式规范,它们的行为符合预期,但不同,应该是相同的。

标签: python c format-specifiers


【解决方案1】:

来自 python 文档:

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


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

精确的规则如下:假设用表示类型'e'和精度p-1格式化的结果将具有指数exp。然后如果 -4

正负无穷、正负零和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 使用小数点后 的数字数。

【讨论】:

【解决方案2】:

来自printf(3) man page

e,e

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

...

g,g

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

因此,即使精度相同,它们也会做不同的事情。

【讨论】:

  • 这表明该行为是有意的。但为什么呢?
  • ... 你想让我告诉你为什么 BCPL 的设计师会这样做吗?抱歉,不是通灵者。
  • 是的,我的问题是为什么。我想也许有一个明显的优势,我没有看到......
【解决方案3】:

我将首先尝试描述%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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-04-27
    • 1970-01-01
    • 1970-01-01
    • 2014-06-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多