两个正数相乘为什么结果是负数

14 篇文章 0 订阅

前言

说来实在惭愧,用spark处理hive表中的数据时,出现了两个正数相乘最后结果显示为负数后我的第一反应竟然有点懵逼,充分说明了自己在使用数据时,对Hive表中的字段类型没有进行充分的了解,当时,第二反应才想起是数据类型导致的数据超出范围了,这个还得归结在当时创建Hive表的时候,没有充分对表中每个字段要存储的数据类型进行充分调查

Java基本数据类型及范围

分类数据类型字节取值范围默认值
布尔boolean1false,truefalse
整数字节型byte1-128~127,即-2^7 ~ 2^7-10
整数短整型short2-32768~32767,即-2^15 ~ 2^15-10
整数整型int4-2147483648~2147483647,即-2^31 ~ 2^31-10
整数长整型long8-9 223 372 036 854 775 808~9 223 372 036 854 775 807,即-2^63 ~ 2^63-10
字符char20~65535,\u0000 ~ \uFFFF\u0000
浮点数单精度浮点数float4负数范围:-3.4028234663852886 × 10^38 ~ -1.40129846432481707 × 10^-45,正数范围:1.40129846432481707 × 10^-45~3.4028234663852886 × 10^380.0f
浮点数双精度浮点数float8负数范围:-1.7976931348623157 × 10^308 ~ -4.94065645841246544 × 10^-324,正数范围:4.94065645841246544 × 10^1.7976931348623157 × 10^3080.0

问题简述

  • Hive表一个字段的类型
total_flow          	int
  • 我的操作
// avg_tf是个正数
total_flow * 25 / avg_tf
  • 出现的问题
    通过抽查total_flow = 113716790,乘以25后为3411503700,avg_tf = 322183360,正常结果约为38,可现实结果约为-1.75…

  • 原因分析
    int最大取值为2147438647,而现在已经达到3411503700,显然远远超过了int的取值范围,因此出现这样的原因

  • 解决方案
    (1)修改字段的类型为Double
    (2)在计算的时候,将字段的换算成量级小一下的,防止超出范围,比如我这里给分子分母同时除以1000,或者先除后乘

后记

这里做一个简答测试:int最大值+1的结果?

public class Type_Of_Data {
    public static void main(String[] args) {
       int a = 2147483647;
       int b = 1;
       int c = a + b;
        System.out.println(c);
    }
}

结果:

-2147483648

为什么超过int最大范围结果成了负数?

这个和计算机如何存储二进制有关,在电脑里是以补码出现的。第一位是符号位。0为正,1为负,当正的除了符号位全为1时候,要是再加一就进位了,导致符号位为1,其他为0,再换成10进制就是你这个数了

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

SunnyRivers

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值