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

How to show true numeric value in Python?

案例一:

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 除外)。


案例二:

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 , ETC)。那么上面的案例 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}"

ACCEPTED ANSWER:澄清了问题中假设的错误前提;实际问题的答案在问题本身内 - 使用 format 显示真实数值。

整数值实数实际上可以完美精确地用二进制表示。 对于每个自然数 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 - 你在这里也可以获得完美的精度。

在常用格式中,例如 IEEE 754 64 位二进制浮点数,所有有限浮点数都是二进制分数,形式为 A*2B 的数字,其中 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 位二进制数的整数都可以精确表示,解释了问题中的第二个 table。 9 是 9*20.

输出端值得注意的是,每个二进制小数都有一个终止十进制扩展。这是 2 是 10 的因数的结果。打印足够的数字,你将得到浮点数的精确值。