关于分布式计算:ODPS-double类型转型精度问题总结

68次阅读

共计 2664 个字符,预计需要花费 7 分钟才能阅读完成。

简介:ODPS double 类型转型精度问题总结

从相差 0.0000000000001 说起,本文次要是对 odps 的 Double 和 Decimal 的精度应用问题做一个总结。

1. 问题形容

客户开发人员在应用 maxcompute 对 double 数据类型求和时呈现谬误(数据表由 oracle 数据库抽取到 maxcompute, 对应字段类型为 number 到 double),正确的后果是 1943.38,但求和后果为 1943.3799999999999,后果相差了 0.0000000000001,这个差值的比例能够这样类比——如果地球的周长(40076.02 千米)作为单位 1 的话,那么误差换算进去是 4 微米,差不多是一个红细胞的大小。绝大多数的状况下,咱们能够疏忽这个问题,然而在金融线,“差一微米也不行”。

2. 问题的根因:double 求和带来精度问题

double 适宜做科学计算,如果用来进行准确计算,会带来精度失落的问题。二进制的浮点数计算规范是 IEEE 二进制浮点数算术规范(ANSI/IEEE Std 754-1985),IEEE 754 规定了四种示意浮点数值的形式:单精确度(32 位)、双精确度(64 位)、延长单精确度(43 比特以上,很少应用)与延长双精确度(79 比特以上,通常以 80 位实现),double 类型通常指“双精确度(64 位)”,53 位有效数字。要了解 double 的精度问题,咱们从最根底的二机制与十进制转换看起,比方:如何用二进制示意 0.1?小数是用整数除法来示意的,0.1=1/10(十进制)=1/1010(二进制),会失去一个除不尽的值,用 double 类型来示意这个数的时候就必须要进行截断(舍入),失去的后果是 0.00011001100110011001100110011001100110011001100110011010,如果把后果转回十进制,会发现这个值曾经不是 0.1,精度问题产生了。同理,double 类型在进行计算也会造成同样的精度问题。

3. 如何解决——double 转型 decimal

double 计算会有精度问题,为了失去准确的后果,就要在计算之前进行解决,转换成无损计算的类型之后,再进行计算,maxcompute 提供了这种无损类型——decimal。

3.1 double 间接转成 decimal 再次遇到问题

可怜的是,间接转型会遇到以下两个问题:
1)转型也会有精度损失。
2)同列的某些值看起来没有精度损失,另一些有,呈现体现不统一的状况。

  • double 间接转 decimal 会带来精度损失,因为 double 的小数位无效位比 decimal 要少,decimal 会对最初的几位进行随机数补齐,引入了精度问题。
  • 同列中某些值没有呈现任何精度损失,因为客户应用了 2.0 数据类型版本,在这个版本中 maxcompute 对转换进行了优化,对位数较小的数(测试后果为 7 位,供参考)采纳了不同的转型算法(相似 decimal 的解决办法,转换成整数进行计算,保障无损)。位数较大的数无奈采纳该算法,规范算法解决,会呈现精度损失。

4. 转换成 decimal 就功败垂成了么?

4.1 incompatible type exception

decimal 类型的计算尽管是无损的,然而 decimal 在计算过程可能会产生精度位数的变动,导致下图中的问题:计算结果插入后果表中时呈现 ”incompatible type” 的谬误。

4.2 如何防止

问题呈现的起因是混用了 1.0 decimal 类型和 2.0 decimal 类型。若想无效的防止 decimal 计算导致的问题,须要遵循:

  • 从建表开始,始终应用同一种数据类型,不要混用。
  • 应用 2.0 数据类型,建源表和后果表时指定具体的 decimal 精度位,如 decimal(35,6),防止计算中精度位数的变动。

5. 防止转型问题的最佳实际

如果心愿防止精度问题,并且在计算过程中防止后果转型,那么能够将所有波及准确计算的字段在建表时就采纳 2.0 数据类型,并且指定所须要的精度,例如:

set odps.sql.decimal.odps2=true;
CREATE TABLE `ods_test` (` account_balance` DECIMAL(38, 18) COMMENT '账户余额'
)

在后续的查问和计算过程中,设置“odps.sql.decimal.odps2=true”后进行操作,例如:

set odps.sql.decimal.odps2=true;
select sum(account_balance) from ods_test

6. 写在最初

本篇次要探讨了计算(数据开发)过程中 double 类型精度问题,maxcompute 在数据集成的过程中会不会产生精度问题?最佳实际是什么?预知后事如何,且听下回分解!

参考文档

[1] https://blog.csdn.net/liliuteng/article/details/8062019
[2] https://cloud.tencent.com/developer/article/1468551
[3] https://blog.csdn.net/lkforce/article/details/81564927
[4] https://www.zhihu.com/question/42024389/answer/93528601
[5] https://help.aliyun.com/product/27797.html?spm=a2c4g.11186623.6.540.615f44f675F7Wi
[6] https://baike.baidu.com/item/IEEE+754/3869922?fr=aladdin

咱们是阿里云智能寰球技术服务 -SRE 团队,咱们致力成为一个以技术为根底、面向服务、保障业务零碎高可用的工程师团队;提供业余、体系化的 SRE 服务,帮忙广大客户更好地应用云、基于云构建更加稳固牢靠的业务零碎,晋升业务稳定性。咱们冀望可能分享更多帮忙企业客户上云、用好云,让客户云上业务运行更加稳固牢靠的技术,您可用钉钉扫描下方二维码,退出阿里云 SRE 技术学院钉钉圈子,和更多云上人交换对于云平台的那些事。

版权申明: 本文内容由阿里云实名注册用户自发奉献,版权归原作者所有,阿里云开发者社区不领有其著作权,亦不承当相应法律责任。具体规定请查看《阿里云开发者社区用户服务协定》和《阿里云开发者社区知识产权爱护指引》。如果您发现本社区中有涉嫌剽窃的内容,填写侵权投诉表单进行举报,一经查实,本社区将立即删除涉嫌侵权内容。

正文完
 0