Java基本数据类型运算

Java基本数据类型及其运算

1. 整型运算

  1. 四则运算

    对于整型类型,Java只定义了带符号的整型,因此,最高位的bit表示符号位(0表示正数,1表示负数)。各种整型能表示的最大范围如下:

  • byte:-128 ~ 127
  • short: -32768 ~ 32767
  • int: -2147483648 ~ 2147483647
  • long: -9223372036854775808 ~ 9223372036854775807

    因此存在溢出情况,求解溢出情况只需要将具体的数换为二进制进行加减即可,如果最高位变为1,则溢出之后的数又会变为负数

    注:没有必要为了节省内存而使用byte和short进行整数运算,范围太小,即使确定了在byte类型内,后期的各种与int的转换会使代码十分冗余,难以维护

    int i = 0
    while(i>0){//不是死循环,因为会溢出变为负数
        i += 1000;
    }
  1. 移位运算

    在计算机种整数总是以2进制的形式存在

    //左移,包括符号位向左截断相应的位数,而右边用0补上
    int shitNum = 15;//00000000 00000000 00000000 00001111
    int shitNumLeft1 = shitNum << 1;//00000000 00000000 00000000 00011110
    System.out.println(shitNumLeft1);//移位之后在转换二进制的时候相当于多乘了一个2, 30
    int shitNumLeft2 = shitNum << 2;//00000000 00000000 00000000 00111110
    System.out.println(shitNumLeft2);//移位之后在转换二进制的时候相当于多乘了两个个2, 60
    int shitNumLeft28 = shitNum << 28;//11110000 00000000 00000000 00000000
    System.out.println(shitNumLeft28);//移位过多可能会造成负数 -268435456,也就是说左移运算用作乘2工具是有风险的
    
    //左移一个负数,带符号移位,可能会变正,但也是乘2
    shitNum = -15;
    int shitNumNevigateLeft = shitNum << 1;
    System.out.println(shitNumNevigateLeft);

    左移相当于乘2,符号位在截断范围内,可能会出现正负交替的情况,如果没有发生有效数位的丢失那么左移几位就相当于乘以几次2,如果移动的位数大于32则先对32求余在移位余数(移33和移1一致),并且移位之后并没有改变原来的数,只是得到一个新数。注:观看以上看出左移是无法用作乘2工具的

     //正数右移就是除2,最后会为0,移出的截断,右边0补充
     int shitNum = 15;//00000000 00000000 00000000 00001111
     int shitNumRight1 = shitNum >> 1;//00000000 00000000 00000000 0000111
     System.out.println(shitNumRight1);//移位之后在转换二进制的时候相当于除一个2,7
     int shitNumRight2 = shitNum >> 2;//00000000 00000000 00000000 00000011
     System.out.println(shitNumRight2);//移位之后在转换二进制的时候相当于除两个个2, 3
     int shitNumRight28 = shitNum >> 28;//00000000 00000000 00000000 00000000
     System.out.println(shitNumRight28);//移位过多可能会造成0
    
    //负数右移也是除2,但是最高位不动,最后为-1,就是 >> 对于负数来说为不带符号位的右移
    int n = -536870912;
    int a = n >> 1;  // 11110000 0000000 0000000 00000000 <= -268435456
    int b = n >> 2;  // 10111000 0000000 0000000 00000000 <= -134217728
    int c = n >> 28; // 10000000 0000000 0000000 00000001 <= -2
    int d = n >> 29; // 10000000 0000000 0000000 00000000 <= -1
    
    //>>> 为带符号位的右移,负数一旦带符号移位就变为正数,但本质绝对值可能不再是除2
    int n2 = -536870912;
    int a2 = n >>> 1;  // 01110000 0000000 0000000 00000000 <= 1879048192
    int b2 = n >>> 2;  // 00111000 0000000 0000000 00000000 <= 939524096
    int c2 = n >>> 29; // 00000000 0000000 0000000 00000111 <= 7
    int d2 = n >>> 31; // 00000000 0000000 0000000 00000001 <= 1

    右移相当于除2,>> 符号位不再移动范围内,>>>符号位在移动范围内,移动位数过多可能会为0,并且右移运算符种的>>一定可以用作除法的工具,而且效率高。如果移动的位数大于32则先对32求余在移位余数(移33和移1一致),并且移位之后并没有改变原来的数,只是得到一个新数。

  2. 位运算

    1. 与运算,两bit同为1为1
    2. 或运算,任意一bit为1为1
    3. 非运算,01互换
    4. 异或运算,两bit不同为1,相同为0

       int i = 167776589; // 00001010 00000000 00010001 01001101
       int n = 167776512; // 00001010 00000000 00010001 00000000
       System.out.println(i & n); // 167776512

2.浮点数运算

浮点数运算与整数运算相比只能进行四则数值运算,不能移位运算,位运算,浮点数的表示范围比整形还要大,但是在计算机内部浮点数无法精确的表示。也就是说浮点数的运算存在误差,因此判断两个浮点数是否相等一般采用差值小于某个一个很小的数

// 比较x和y是否相等,先计算其差的绝对值:
double r = Math.abs(x - y);
// 再判断绝对值是否足够小:
if (r < 0.00001) {
    // 可以认为相等
} else {
    // 可以认为不相等
}

注:整数除0时会报错,浮点数除0时返回特殊值

double d1 = 0.0 / 0; // NaN
double d2 = 1.0 / 0; // Infinity
double d3 = -1.0 / 0; // -Infinity

3.布尔运算

boolean永远只有true和false两种值

短路运算 && || ,值得一提的是三元运算符也是短路运算符,确定结果之后不会执行剩下的表达式

4. 字符字符串

在Java种字符和字符串是两种不同的类型

4.1char

基本数据类型,一个char保存一个Unicode字符,可以直接将字符赋给char变量,也可以转义字符u+Unicode编码值赋值,将字符赋给int类型就可以看到对应的Unicode编码。

关于Unicode编码介绍请看

char c = 'a';
char c = '\u0041';
int unicodeVlaue = 'a';

4.2String

引用类型变量,String具有不可变性,因为源码中用final 修饰了char[] ,因此二次对同一string变量赋值,其实是创建了新的字符串对象将引用直接替换了,原来的String对象将被垃圾回收机制回收。

String = "123 ";//可以包含空格
String = " 123 \"";//String 种用""标识字符串的开始结束,如果字符串本身包含",就用\",也有其他的转义字符

String message = "输出:";
int num = 9;
System.out.println(message + num);//+ 为字符串拼接,可以在多个字符串之间执行,也可以用字符串与其他任何类型进行拼接,形成新的字符串

引用类型变量的值可以为null值

你可能感兴趣的:(位运算,java,运算符)