java中Long类型溢出引发的思考

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 方法计算两个数字相乘的结果。

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)