了解 pyspark 的 Float 转换行为

Understanding the Float conversion behaviour of pyspark

提问人:Yannick Widmer 提问时间:11/16/2022 更新时间:11/16/2022 访问量:580

问:

当我将python浮点数77422223.0转换为spark FloatType时,我得到77422224。如果我使用 DoubleType 这样做,我会得到77422223。这种转换是如何工作的,有没有办法计算何时会发生这样的错误?

df = spark.createDataFrame([77422223.0],FloatType())
display(df)

输出

enter image description here

并按预期运行

df = spark.createDataFrame([77422223.0],DoubleType())
display(df)

收益 率

enter image description here

apache-spark pyspark 浮点 类型转换 精度

评论

0赞 Steve Summit 11/17/2022
假设我告诉你,你可以在小数点后有三个位置。这意味着您可以精确表示 1234.567 和 1234.568,但不能表示 1234.5678。假设我告诉你,你总共可以有七个有效数字。这意味着您可以精确表示 1234.567、12345.67 和 123456.7。您甚至可以表示 1234567.0。但你不能代表 12345678.0!这需要八位有效数字,我说你只能有七位。因此,您可以表示 12345670.0 或 12345680.0,但不能介于两者之间。
0赞 Steve Summit 11/17/2022
计算机浮点使用二进制,而不是十进制,并且您可以拥有的有效位数有限制,但总体原则是相同的。转换为二进制的数字77422223需要 27 位。这比单精度浮点通常可以保持的精度更高:该类型的最大精度通常为 24 位。因此,您可以表示 77422216.0 或 77422224.0,但不能介于两者之间。
0赞 Steve Summit 11/17/2022
但是精度浮点的精度高达53位,因此可以精确地表示77422223.0。

答:

1赞 Eric Postpischil 11/16/2022 #1

这种转换是如何工作的......

我假设 Spark 是 IEEE-754 二进制32。此格式使用 24 位有效数和从 −126 到 +127 的指数范围。每个数字都表示为一个符号和一个 24 位数字,其第一个数字后面有一个“.”乘以 2 的指数幂,例如 +1.01001100001111100000000 2•2 13FloatType

在二进制中,77,422,223 是2 100100111010101111010001111。那是 27 位。所以它不能用 binary32 格式表示。当它转换为 binary32 格式时,转换操作会将其舍入到最接近的可表示值。即1001001110101011110100100002,它有 23 位有效数字。

...有没有办法计算何时会发生这样的错误?

当数字以二进制形式写入时,如果从前 1 到后 1 的位数(包括这两个位数)超过 24,则它不能以 binary32 格式表示。

此外,如果该数字的大小小于 2−126,则它不能用 binary32 表示,除非它是 2−149 的倍数,包括零。此范围内的数字是次正态的,具有固定的指数 -126,有效值的最低位的位置值为 2-149。而且,如果震级数为 2128 或更大,则无法表示,除非它是 +∞ 或 −∞。