如何在Python中显示真实的数值?

时间:2019-11-30 15:59:14

标签: python floating-point precision floating-accuracy

案例1

for num in [.1, .2, .3, .4, .5, .6, .7, .8, .9,]:
    print(format(num, ".50f"))
0.10000000000000000555111512312578270211815834045410
0.20000000000000001110223024625156540423631668090820
0.29999999999999998889776975374843459576368331909180
0.40000000000000002220446049250313080847263336181641
0.50000000000000000000000000000000000000000000000000
0.59999999999999997779553950749686919152736663818359
0.69999999999999995559107901499373838305473327636719
0.80000000000000004440892098500626161694526672363281
0.90000000000000002220446049250313080847263336181641

精度不高(.5除外)。


案例2

for num in [1., 2., 3., 4., 5., 6., 7., 8., 9.]:
    print(format(num, ".50f"))
1.00000000000000000000000000000000000000000000000000
2.00000000000000000000000000000000000000000000000000
3.00000000000000000000000000000000000000000000000000
4.00000000000000000000000000000000000000000000000000
5.00000000000000000000000000000000000000000000000000
6.00000000000000000000000000000000000000000000000000
7.00000000000000000000000000000000000000000000000000
8.00000000000000000000000000000000000000000000000000
9.00000000000000000000000000000000000000000000000000

完美的精度-???


众所周知,计算中没有完美的浮点整数:所有浮点都以二进制为基础来表示,精度取决于位大小(float32float64等)。那么,上述案例2的处理方式是什么?即使对于".1000f",零也将持续存在,这基本上意味着无限的精度。此外,0.5也以某种方式完美体现。

如果format不能强制Python打印浮点数的“ true”值,那怎么办?


尝试的替代方法

  1. format(round(num, 50), ".50f")
  2. format(numpy.float128(num), ".50f")
  3. format(round(numpy.float128(num), 50), ".50f")
  4. format("%.50f" % num)
  5. "{:.50f}".format(num))
  6. f"{num:.50f}"

接受的答案:阐明问题中假定的错误前提;实际问题的答案就在问题本身之内-使用format显示真实的数值。

2 个答案:

答案 0 :(得分:4)

在常用格式中,例如IEEE 754 64位二进制浮点数,所有有限浮点数都是二进制分数,形式为A * 2 B 的数字,其中A和B均为带符号整数。

当然,有限格式只能表示二进制分数的有限子集。 A中的有效位数和B的范围均受格式限制。对于普通的(非次普通的)IEEE754 64位二进制文​​件,A的有效位不能超过53个,并且非零的A标准化为1.x形式时,B必须在[−1022,1023]范围内

0.5可以精确表示,因为它是1 * 2 -1 。 同样,诸如5.0 / 8.0(5 * 2 -3 )之类的数字也是准确的。

在64位二进制浮点数中,可以精确表示适合32位二进制数的所有整数,从而解释了问题中的第二张表。 9是9 * 2 0

对于输出端值得注意的是,每个二进制小数都有一个终止的十进制扩展名。这是2乘以10的结果。打印足够的数字,您将获得浮点数的确切值。

答案 1 :(得分:1)

整数值实数实际上可以完美的精度用二进制表示。 对于每个自然数n,都存在一个自然数k,以及一个0-s和1-s的序列,使得:

n = b0 *(2 ^ 0)+ b1 *(2 ^ 1)+ ... + bk *(2 ^ k)

这当然适用,即使您使用float类型。该数字以有限的位数存储,因此具有无限的精度。

一些有理数也可以是-具体来说,可以表示为:

s = b1 *(0.5)^ 1 + b * 2(0.5)^ 2 + ... + b * k(0.5)^ k + n

对于某些自然数k,n和一个二进制向量

这就是为什么您获得0.5的完美精度,而不获得其他分数值的原因。尝试使用0.75,例如,您在这里也会获得完美的精度。