Hive中可变小数位字符串转double问题:转换结果异常
解决可变小数位字符串转数值的精度问题
刚好碰到过类似的场景,给你梳理下为啥之前的转换会出问题,再给你两个靠谱的解决方案:
为啥之前的方法不行?
- 用
cast(RECURR as float)出现误差:float是单精度浮点数,它最多只能保证约7位十进制有效数字的精度,而你的字符串有9位有效数字,转换时自然会产生舍入误差,导致结果变成359.880004882813这种偏离原始值的情况。 - 用
cast(RECURR as decimal)得到整数:默认的decimal类型是decimal(18,0)——也就是没有小数位,所以数据库会自动把所有小数部分四舍五入到整数,结果自然变成360了。
解决方案
方案1:转双精度浮点数(满足double类型需求)
如果你的目标就是得到double类型,直接用双精度类型转换就行。双精度(比如SQL里的double或者float(53))的精度能覆盖15-17位十进制有效数字,完全hold住你的9位数值,不会出现单精度的误差:
cast(RECURR as double) as RECURR
比如359.879999转完后就是精确的359.879999,完美匹配你的预期。
方案2:转高精度decimal类型(绝对精确)
如果涉及到需要精确计算的场景(比如财务数据),更推荐用decimal类型,只要指定足够的精度和小数位就行。你的字符串最多有8位小数(比如3.59879999),整数部分最多3位,所以用decimal(18,8)就足够容纳所有情况:
cast(RECURR as decimal(18,8)) as RECURR
转换后原始数值会被精确保留,比如359.879999会变成359.87999900(数值上和原始值完全一致),3.59879999则会精准保留为3.59879999。
要是你的数据库支持numeric类型,它和decimal是等价的,用cast(RECURR as numeric(18,8))也一样管用。
内容的提问来源于stack exchange,提问作者Wesley Kluckhohn
相关产品推荐
相关产品推荐

