在Java中:
String test1 = String.format("%7.2g", 3e9);
System.out.println(test1);
这会打印3.0e+09
在Python 2.7中,如果我运行此代码
for num in [3e9, 3.1e9, 3.01e9, 3e2, 3.1e2, 3.01e2]:
print '%7.2g %7.2f %7.2e' % (num, num, num)
我得到了
3e+09 3000000000.00 3.00e+09
3.1e+09 3100000000.00 3.10e+09
3e+09 3010000000.00 3.01e+09
3e+02 300.00 3.00e+02
3.1e+02 310.00 3.10e+02
3e+02 301.00 3.01e+02
咦?看起来精确(.2)参数在Python %g
中的处理方式与Python的%f
,Python的%e
或Java的%g
完全不同。这是doc(我的重点):
一般格式。对于给定的精度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.
WTF?有没有办法防止这些尾随零被删除?字符串格式化的重点是实现一些一致性,例如用于文本对齐。
有没有办法获得Java行为(基本上是小数点右边的有效位数),而不必从头开始重写整个事物?
答案 0 :(得分:2)
使用format
方法,您可以执行以下操作:
for num in [3e9, 3.1e9, 3.01e9, 3e2, 3.1e2, 3.01e2]:
print ('{n:7.2{c}} {n:7.2f} {n:7.2e}'.format(n=num, c='e' if num > 1e4 else 'f'))
输出:
3.00e+09 3000000000.00 3.00e+09
3.10e+09 3100000000.00 3.10e+09
3.01e+09 3010000000.00 3.01e+09
300.00 300.00 3.00e+02
310.00 310.00 3.10e+02
301.00 301.00 3.01e+02
它有两个部分可能不太为人所知。
除了简单的格式:
>>> '{}'.format(3.5)
'3.5'
并使用更详细的结果规范进行格式化:
>>> '{:5.2f}'.format(3.5)
' 3.50'
您可以在format
中使用可以在字符串中访问的关键字参数:
>>> '{num:5.2f}'.format(num=3.5)
' 3.50'
您也可以将这些用于格式规范本身:
>>> '{:5.{deci}f}'.format(3.5, deci=3)
'3.500'
if
表达式除if
语句外,还有一个if
表达式,a.k.a。ternary operator。
所以,这个表达式:
a = 1
b = 2
res = 10 if a < b else 20
等同于此声明:
if a < b:
res = 10
else:
res= 20
将两者放在一起会产生如下结果:
'{num:7.2{c}}'.format(num=num, c='e' if num > 1e4 else 'f')
答案 1 :(得分:2)
python所做的格式与C&#printf
样式格式更加一致,后者也会为g
转换删除尾随零。由于python的引用实现在C中,为什么在这种情况下它应该与Java保持一致?
使用%
运算符进行字符串格式化时,相关文档为String Formatting Operations,与您链接的文档存在一些差异,特别是它允许使用#
备用表格g
:
备用表单会导致结果始终包含小数点,并且不会删除尾随零,否则它们将被删除。
精度确定小数点前后的有效位数,默认为6。
所以在你的情况下:
>>> "%#7.2g" % 3e9
3.0e+09
这与str.format()
允许的不同,其中#
用于为二进制,八进制或十六进制输出启用前缀(至少在python2中,这在python3中已更改)。