java中Long类型溢出引发的思考
2017-09-12 23:59
316 查看
long var = 数字常量(数字常量大于等于2^31),实际上,此时的var 的值为溢出后的值;
溢出之后会变为负值和预期作不符。
并且编译器不报错,但是结果和预期不符。
在检查bug过程中 要注意所赋值不能超过该变量自身的最大值,其他类型也是如此。
byte的取值范围为-128~127,占用1个字节(-2的7次方到2的7次方-1)
short的取值范围为-32768~32767,占用2个字节(-2的15次方到2的15次方-1)
int的取值范围为(-2147483648~2147483647),占用4个字节(-2的31次方到2的31次方-1)
long的取值范围为(-9223372036854774808~9223372036854774807),占用8个字节(-2的63次方到2的63次方-1)
出现的问题:long long zs=2000000000ll*100ll; 计算结果为负值。 ll告诉编译器,把这数字看成long* long的。结果为负值。
解决方法
1.避免使用两个long类型的数直接相乘。
2.或者使用BigDecimal 方法计算两个数字相乘的结果。
bigInterge和bigdecimal的区别和联系
BigInteger相比Integer的确可以用big来形容。它是用于科学计算,Integer只能容纳一个int, 所以最大值也就是2的31次访减去1,十进制为2147483647,如果需要计算更大的数,那么31位显然是不够用了,BigInteger能够容纳的位数那可就大了,我简单试了一下,上千位没有任何问题。除了容量大之外,BigInteger还封装了一些常见的操作,比如+-*/的基本操作,还有绝对值,相反数,最大公约数,是否是质数等等的运算。
BigDecimal的实现利用到了BigInteger, 所不同的是BigDecimal加入了小数位的概念,比如BigDecimal d = new BigDecimal(new BigInteger(ib),5);5表示的是5个小数位。BigDecimal可以用来做超大的浮点数的运算,比如+-*/的运算,其中除法运算是最复杂的,因为商的位数还有除不断的情况下末位小数点的处理都是需要考虑的。
new BigDecimal(-7.5).divide(new BigDecimal(1),0,BigDecimal.ROUND_UP);
上面的这个运算中divide的第二个参数表示商的小数点位数,最后一个参数指的是近似处理的模式。一共有一下几个模式:
BigDecimal.ROUND_UP 最后一位如果大于0,则向前进一位,正负数都如此。
BigDecimal.ROUND_DOWN 最后一位不管是什么都会被舍弃。
BigDecimal.ROUND_CEILING 如果是正数,按ROUND_UP处理,如果是负数,按照ROUND_DOWN处理。例如7.1->8; -7.1->-7;所以这种近似的结果都会>=实际值。
BigDecimal.ROUND_FLOOR 跟BigDecimal_ROUND_CEILING相反。例如7.1->7;-7.1->-8。这种处理的结果<=实际值。
BigDecimal.ROUND_HALF_DOWN 如果最后一位<=5则舍弃,如果>5, 向前进一位。如7.5->7;7.6->8;-7.5->-7
BigDecimal.ROUND_HALF_UP 如果最后一位<5则舍弃,如果>=5, 向前进一位。反之舍弃。如7.5->8;7.4->7;-7.5->-8
BigDecimal.ROUND_HALF_EVEN 如果倒数第二位是奇数,按照BigDecimal.ROUND_HALF_UP处理,如果是偶数,按照BigDecimal.ROUND_HALF_DOWN来处理。如7.5->8;8.5->8;7.4->7;-7.5->-8
溢出之后会变为负值和预期作不符。
并且编译器不报错,但是结果和预期不符。
在检查bug过程中 要注意所赋值不能超过该变量自身的最大值,其他类型也是如此。
byte的取值范围为-128~127,占用1个字节(-2的7次方到2的7次方-1)
short的取值范围为-32768~32767,占用2个字节(-2的15次方到2的15次方-1)
int的取值范围为(-2147483648~2147483647),占用4个字节(-2的31次方到2的31次方-1)
long的取值范围为(-9223372036854774808~9223372036854774807),占用8个字节(-2的63次方到2的63次方-1)
出现的问题:long long zs=2000000000ll*100ll; 计算结果为负值。 ll告诉编译器,把这数字看成long* long的。结果为负值。
解决方法
1.避免使用两个long类型的数直接相乘。
2.或者使用BigDecimal 方法计算两个数字相乘的结果。
public static void main(String[] args) throws Exception { long a = Long.MAX_VALUE; long b = Long.MAX_VALUE; BigDecimal ba = new BigDecimal(String.valueOf(a)); BigDecimal bb = new BigDecimal(String.valueOf(b)); BigDecimal bc = ba.multiply(bb); System.out.println(String.valueOf(a)); System.out.println(String.valueOf(b)); System.out.println(bc); }
bigInterge和bigdecimal的区别和联系
BigInteger相比Integer的确可以用big来形容。它是用于科学计算,Integer只能容纳一个int, 所以最大值也就是2的31次访减去1,十进制为2147483647,如果需要计算更大的数,那么31位显然是不够用了,BigInteger能够容纳的位数那可就大了,我简单试了一下,上千位没有任何问题。除了容量大之外,BigInteger还封装了一些常见的操作,比如+-*/的基本操作,还有绝对值,相反数,最大公约数,是否是质数等等的运算。
BigDecimal的实现利用到了BigInteger, 所不同的是BigDecimal加入了小数位的概念,比如BigDecimal d = new BigDecimal(new BigInteger(ib),5);5表示的是5个小数位。BigDecimal可以用来做超大的浮点数的运算,比如+-*/的运算,其中除法运算是最复杂的,因为商的位数还有除不断的情况下末位小数点的处理都是需要考虑的。
new BigDecimal(-7.5).divide(new BigDecimal(1),0,BigDecimal.ROUND_UP);
上面的这个运算中divide的第二个参数表示商的小数点位数,最后一个参数指的是近似处理的模式。一共有一下几个模式:
BigDecimal.ROUND_UP 最后一位如果大于0,则向前进一位,正负数都如此。
BigDecimal.ROUND_DOWN 最后一位不管是什么都会被舍弃。
BigDecimal.ROUND_CEILING 如果是正数,按ROUND_UP处理,如果是负数,按照ROUND_DOWN处理。例如7.1->8; -7.1->-7;所以这种近似的结果都会>=实际值。
BigDecimal.ROUND_FLOOR 跟BigDecimal_ROUND_CEILING相反。例如7.1->7;-7.1->-8。这种处理的结果<=实际值。
BigDecimal.ROUND_HALF_DOWN 如果最后一位<=5则舍弃,如果>5, 向前进一位。如7.5->7;7.6->8;-7.5->-7
BigDecimal.ROUND_HALF_UP 如果最后一位<5则舍弃,如果>=5, 向前进一位。反之舍弃。如7.5->8;7.4->7;-7.5->-8
BigDecimal.ROUND_HALF_EVEN 如果倒数第二位是奇数,按照BigDecimal.ROUND_HALF_UP处理,如果是偶数,按照BigDecimal.ROUND_HALF_DOWN来处理。如7.5->8;8.5->8;7.4->7;-7.5->-8
相关文章推荐
- Java int基本类型和Integer之间引发的问题思考
- 由【JAVA中参数传递问题】引发除了基本数据类型和引用类型的思考
- JAVA中关于int类型相乘溢出
- 一道面试题引发的对javascript类型转换的思考
- Java中由常量类引发的思考
- 一次聊天引发的思考--java并发包
- 关于java 中日期类型与数据库打交道时的思考
- Java包命名规则引发的思考
- java中Long类型转化为int类型
- Java 日期时间 Date类型,long类型,String类型表现形式的转换
- Java与垃圾回收技术类型的学习思考
- java中数据类型转换 Integer String Long Float Double Date
- Java中long数据类型转化为float疑问解答
- 在java中已经规定数据类型是长整形为什么数字后面还要加一个"l"啊?前面不是有long吗?
- 关于java 中日期类型与数据库打交道时的思考
- Java中关于为什么long能自动转换成float类型的疑问解决
- 由一道 Java finally 执行顺序的题引发的思考
- Java中的String和Date、Timestamp之间的转换+long类型的陷阱
- 关于Java内存溢出的一些思考
- 解决Java中Long类型转换成Json时,在Js代码调用时精度丢失的问题