Spark中Double类型除法精度异常问题及无round操作解决方案咨询
问题原因与解决方案
问题原因
这是二进制浮点数的精度固有缺陷导致的:
double属于二进制浮点数类型,它依赖二进制编码存储数值,但很多十进制小数(比如10.62)无法被二进制精确表示,只能存储一个近似值。- 当你把"10.62"转成
double后,实际存储的是一个接近10.62但略有偏差的二进制值,除以100后,这个微小偏差被放大显现,就得到了0.10619999999999这类近似结果。
无需round的解决方案
用Spark的DecimalType(十进制精确数值类型)替代double,就能从根源上避免该问题——Decimal基于十进制规则存储数值,可以精确表示十进制小数。
示例代码:
import org.apache.spark.sql.types.DecimalType import org.apache.spark.sql.functions.{lit, regexp_replace} // 方案1:转换为DecimalType后执行运算 .withColumn("percentage", regexp_replace(lit("10.62%"), "%", "").cast(DecimalType(10, 2)) / 100 ) // 方案2:直接使用Decimal类型字面量运算(若数值固定) .withColumn("percentage", lit(10.62).cast(DecimalType(10, 2)) / 100)
通过这种方式得到的结果就是精确的0.1062,不需要额外的round操作。
内容的提问来源于stack exchange,提问作者Alexander Lopatin
相关产品推荐
相关产品推荐

