ODPS double类型转型精度问题总结

ODPS double类型转型精度问题总结简介:ODPSdouble类型转型精度问题总结从相差0.0000000000001说起,本文主要是对odps的Double和Decimal的精度使用问题做一个总结。1.问题描述客户开发人员在使用maxcompute对double数据类型求和时出现错误(数据表由oracle数据库抽取到maxcompute,对应字段类型为number到double),正确的结果是1943.38,但求和结果为1943.3799999999999,结果相差了0.0000000000001,这个…

大家好,又见面了,我是你们的朋友全栈君。

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

 

image.png

 

从相差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)同列的某些值看起来没有精度损失,另一些有,出现表现不一致的情况。

 

image.png

 

  • double直接转decimal会带来精度损失,因为double的小数位有效位比decimal要少,decimal会对最后的几位进行随机数补齐,引入了精度问题。
  • 同列中某些值没有出现任何精度损失,因为客户使用了2.0数据类型版本,在这个版本中maxcompute对转换进行了优化,对位数较小的数(测试结果为7位,供参考)采用了不同的转型算法(类似decimal的处理方法,转换成整数进行计算,保证无损)。位数较大的数无法采用该算法,标准算法处理,会出现精度损失。

4. 转换成decimal就大功告成了么?

4.1 incompatible type exception

decimal类型的计算虽然是无损的,但是decimal在计算过程可能会产生精度位数的变化,导致下图中的问题:计算结果插入结果表中时出现”incompatible type”的错误。

 

image.png

 

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%20754/3869922?fr=aladdin

我们是阿里云智能全球技术服务-SRE团队,我们致力成为一个以技术为基础、面向服务、保障业务系统高可用的工程师团队;提供专业、体系化的SRE服务,帮助广大客户更好地使用云、基于云构建更加稳定可靠的业务系统,提升业务稳定性。

原文链接

本文为阿里云原创内容,未经允许不得转载。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/162210.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 前嗅ForeSpider教程:抽取数据

    前嗅ForeSpider教程:抽取数据

    2021年7月1日
    94
  • java 程序中的指令重排是什么_指令和程序的区别和联系

    java 程序中的指令重排是什么_指令和程序的区别和联系Java中有两个编译期:1、编译期:调用javac命令将Java代码编译成Java字节码;2、运行期:JIT编译器将字节码编译成机器码。指令重排指令重排是指在程序执行过程中,为了性能考虑,编译器和CPU可能会对指令重新排序。…

    2022年10月17日
    3
  • python 画图命令[通俗易懂]

    python 画图命令[通俗易懂]画图importmatplotlib.pyplotaspltplt.rcParams[‘font.sans-serif’]=[‘SimHei’]#用来正常显示中文标签plt.rcParams[‘axes.unicode_minus’]=False#用来正常显示负号plt.figure()plt.plot(x_data,y_data,color="red",linewidth=2)…

    2022年5月25日
    32
  • “栈”的典型应用—表达式求值(C语言实现)

    “栈”的典型应用—表达式求值(C语言实现)表达式求值是程序设计语言编译中的一个基本问题。它的实现就是对“栈”的典型应用。本文针对表达式求值使用的是最简单直观的算法“算符优先法”。我们都知道算术四则运算的运算规则是:先乘除,后加减。从左到右计算先算括号内,再算括号外表达式组成任何一个表达式都有操作数、运算符和界定符组成。操作数即可以是常量,也可以是被说明为变量或常量的标识符。运算符可以分为算术运算,关系运算和

    2022年6月15日
    34
  • 计算机网络ip地址划分范围,ip地址分类及范围划分有哪些

    计算机网络ip地址划分范围,ip地址分类及范围划分有哪些ip地址分为网络地址和主机地址,IP地址是真正网络中计算机的身份标识。手机的IP是手机上网使用的地址,不论是手机还是电脑,一个网段里面只有一个IP,所以每个人手机的IP都是唯一的,当用手机发朋友圈时,就会显示手机ip地址所在地,因此有些人会想要修改手机ip地址。那么ip地址可分为哪几类?其范围是怎么划分的?如何修改手机ip地址?下面小编为大家解答手机ip地址修改方法及ip地址分类及范围划分等知识。…

    2022年5月29日
    50
  • BestMPRBaseVtk-009-设置默认窗宽窗位

    BestMPRBaseVtk-009-设置默认窗宽窗位今天我们来解决一个小问题,就是让图像加载完了,按照图像自带的窗宽窗位显示,这么形容不知道是否准确,大概意思就是这样吧。目前和MITK对比如下图所示:

    2022年6月23日
    40

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号