Java之整数运算
Java的整数运算遵循四则运算规则,可以使用任意嵌套的小括号。四则运算规则和初等数学一致。例如:
public class Main {
public static void main(String[] args) {
int i=(100+200)*(99-88);//3300
int n=7*(5+(i-9));//23072
System.out.println(i);
System.out.println(n);
}
}
输出
3300
23072
整数运算的数值不但是精确的,而且整数运算永远是精确的,即使是出发,因为两个整数相除只得到结果的整数部分,不进行四舍五入
int x=11/3;
求余运算
int x=11%3;
整数除法对于被除数为0运行时报错,但编译时不报错

溢出
整数由于存在范围限制,如果计算结果超出了范围,就会产生溢出,而溢出不会报错而会得到一个奇怪的结果。
public class Main {
public static void main(String[] args) {
int x=2147483640;
int y=15;
int sum=x+y;
System.out.println(sum);
}
}
运行结果
-2147483641
要解释上述结果,我们把整数2147483640和15换成二进制做加法
0111 1111 1111 1111 1111 1111 1111 1000
+ 0000 0000 0000 0000 0000 0000 0000 1111
1000 0000 0000 0000 0000 0000 0000 0111
由于最高位计算结果为1,因此加法结果变成了一个负数
要解决上面的文件,可以把int换成long类型,由于long可表示的整型范围更大,所以结果不会溢出
public class Main {
public static void main(String[] args) {
long x=2147483640;
long y=15;
long sum=x+y;
System.out.println(sum);
}
}
还有一种简写的运算符,即+=,-=,*=,/=,使用方法如下
n+=100; //相当于n=n+100
n-=100;//相当于n=n-100
自增/自减
Java还提供了++运算和--运算,它们可以对一个整数进行加1和减1的操作:
public class Main {
public static void main(String[] args) {
int n=100;
n++;
System.out.println(n);
n--;
System.out.println(n);
}
}
注意++写在前面和后面计算结果是不同的,++n表示先加1再引用n,n++表示先引用n再加1。不建议把++运算混入到常规运算中,容易自己把自己搞懵了。
移位运算
在计算机中,整数总是以二进制的形式表示。例如,int类型的整数7使用4字节表示的二进制如下:
00000000 00000000 00000000 00000111
可以对整数进行移位运算。对整数7左移1位将得到整数14,左移2位将得到整数28
int n = 7; // 00000000 00000000 00000000 00000111 = 7
int a = n << 1; // 00000000 00000000 00000000 00001110 = 14
int b = n << 2; // 00000000 00000000 00000000 00011100 = 28
int c = n << 28; // 01110000 00000000 00000000 00000000 = 1879048192
int d = n << 29; // 11100000 00000000 00000000 00000000 = -536870912
左移29位时,由于最高位变成了1,因此结果变成了负数
类似地对证书7进行右移结果如下
int n = 7; // 00000000 00000000 00000000 00000111 = 7
int a = n >> 1; // 00000000 00000000 00000000 00000011 = 3
int b = n >> 2; // 00000000 00000000 00000000 00000001 = 1
int c = n >> 3; // 00000000 00000000 00000000 00000000 = 0
如果对一个负数进行右移,最高位1不动,结果仍然是一个负数
int n = -536870912;
int a = n >> 1; // 11110000 00000000 00000000 00000000 = -268435456
int b = n >> 2; // 10111000 00000000 00000000 00000000 = -134217728
int c = n >> 28; // 11111111 11111111 11111111 11111110 = -2
还有一种不带符号的右移运算,使用>>>,它的特点是符号位跟着动,因此,对一个负数进行>>>右移,它会变成正数,原因是最高位的1变成了0:
int n = -536870912;
int a = n >>> 1; // 01110000 00000000 00000000 00000000 = 1879048192
int b = n >>> 2; // 00111000 00000000 00000000 00000000 = 939524096
int c = n >>> 29; // 00000000 00000000 00000000 00000111 = 7
int d = n >>> 31; // 00000000 00000000 00000000 00000001 = 1
对byte和short类型进行位移时,会首先转换为int再进行位移
左移实际上就是不断地*2,右移实际上就是不断地/2
位运算
位运算是按位进行与,或,非和异或的运算。
与运算的规则是,必须两个数同时为1,结果才为1
n=0 & 0;//0
n=0 & 1;//0
n=1 & 0;//0
n=1 & 1;//1
或运算的规则是,只要任意一个为1,结果就为1
n = 0 | 0; // 0
n = 0 | 1; // 1
n = 1 | 0; // 1
n = 1 | 1; // 1
非运算的规则是,0和1呼唤
n = ~0; // 1
n = ~1; // 0
异或运算的规则是,如果两个数不同,结果为1,否则为0
n = 0 ^ 0; // 0
n = 0 ^ 1; // 1
n = 1 ^ 0; // 1
n = 1 ^ 1; // 0
对于两个整数的运算,实际上就是按位对齐,然后依次对每一位进行运算。例如
public class Main {
public static void main(String[] args) {
int i = 167776589;
int n = 167776512;
System.out.println(i&n);
}
}
运行结果
167776512
上述按位与运算实际上可以看作两个整数表示的IP地址10.0.17.77和10.0.17.0,通过与运算,可以快速判断一个IP是否在给定的网段内。
运算优先级
在Java的计算表达式中,运算优先级从高到低依次是:
()!~++--*/%+-<<>>>>>&|+=-=*=/=
记不住也没关系,只需要加括号就可以保证运算的优先级正确。
类型的自动提升与强制转型
在运算过程中,如果参与运算的两个数类型不一致,那么计算结果为较大类型的整型。例如,short和int计算,结果总是int,原因是short首先自动被转型为int:
public class Main {
public static void main(String[] args) {
short s = 1234;
int i = 123456;
int x = s + i; //s自动转换为int
short y = s + i;//编译错误
}
}
也可以将结果强制转型,即将大范围的整数转型为小范围的整数。强制转型使用(类型),例如,将int强制转型为short:
int i=12345;
short s = (short) i;//12345
超出范围的强制转型会得到错误的结果,原因是转型时,int的两个高位直接直接被扔掉,仅保留了低位的两个字节。
举例说明
public class Main {
public static void main(String[] args) {
int i1 = 1234567;
short s1 = (short) i1; // -10617
System.out.println(s1);
int i2 = 12345678;
short s2 = (short) i2; // 24910
System.out.println(s2);
}
}
结果
-10617
24910
为什么结果是-10617和24910呢
首先把1234567转换成二进制并且使用8位分割成4份
00000000 00010010 11010110 10000111
强制转换成short类型或高位被抛弃留下低位两个字节
11010110 10000111
最高位为1是负数,负数是以补码的形式存储在计算机内需要转换成原码
原码等于补码-1后除符号位取反
补码-1结果
11010110 10000110
除符号位取反得到原码
10101001 01111001
最高位为1所以是负数101001 01111001即-10617
同理计算12345678去掉高两位后剩下的最高位为0是正数则补码和原码是一样的
练习
计算自然数之和
public class Main {
public static void main(String[] args) {
int n=100;
int sum=0;
for(int i=1;i<=n;i++) {
sum=sum+i;
}
System.out.println(sum);
}
}
小结
整数运算的结果永远都是精确的
运算结果会自动提升
可以强制转型,但超出范围的强制转型会得到错误的结果
应该选择合适范围的整型(int或long),没有必要为了节省内存而使用byte和short进行整数运算。
Java之整数运算的更多相关文章
- java 取模运算% 实则取余 简述 例子 应用在数据库分库分表
java 取模运算% 实则取余 简述 例子 应用在数据库分库分表 取模运算 求模运算与求余运算不同.“模”是“Mod”的音译,模运算多应用于程序编写中. Mod的含义为求余.模运算在数论和程序设计中 ...
- 廖雪峰Java1-2Java程序基础-3整数运算
1.四则运算规则 int i =(100 + 200) * (99 -88);//3300 int n = i + 9;//3309 //除法结果为整数 int q = n / 100;//33 // ...
- Java打印整数的二进制表示(代码与解析)
Java打印整数的二进制表示(代码与解析) int a=-99; for(int i=0;i<32;i++){ int t=(a & 0x80000000>>>i)&g ...
- Java之浮点数运算
浮点数运算和整数运算相比,只能进行加减乘除这些数值运算,不能做位运算和移位运算. 在计算机中,浮点数虽然表示的范围很大,但是浮点数有个非常重要的特点,就是浮点数常常无法精确表示 举例 浮点数0.1在计 ...
- Java的位运算 待整理
位运算:二进制运算 Java的异或运算^ 真^假=真 假^真=真 假^假=假 真^真= 假,这四个是在网上copy的例子,真是1,假是0 但它却是说明了Java异或运算的基本法则,那就是:只要两个条件 ...
- java 基础 整数类型
1.Java有四种整数类型:byte.short.int和long. 2.Java默认整数计算的结果是int类型. 3.整数的字面量是int类型. 4.若字面量超过int类型的最大值,则字面量是lon ...
- linux系统中的命令替换与整数运算$(),$(())
一.$()与`` 在 bash shell 中,$( ) 与 ` ` (反引号) 都是用来做命令替换(command substitution)用的. 所谓的命令替换与我们第五章学过的变量替换差不多, ...
- 用WebService实现两个整数运算
最近,项目开发中需要用到Web Service.自己在网上搜集资料.自己做了一个小例子,用来加深自己对Web Service理解. 概念:Web Service主要是为了使原来各孤立的站点之间的信息能 ...
- 九度OJ 1037:Powerful Calculator(强大的计算器) (大整数运算)
时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:1821 解决:528 题目描述: Today, facing the rapid development of business, SJTU ...
随机推荐
- Kotlin高阶函数与函数式编程详解
函数可变参数: 在上一次https://www.cnblogs.com/webor2006/p/11518425.html中学到了可变参考,关于可变参数有如下规则说明: “一个方法中,只允许一个参数为 ...
- Product Oriented Recurrence(Codeforces Round #566 (Div. 2)E+矩阵快速幂+欧拉降幂)
传送门 题目 \[ \begin{aligned} &f_n=c^{2*n-6}f_{n-1}f_{n-2}f_{n-3}&\\ \end{aligned} \] 思路 我们通过迭代发 ...
- linux Crontab定时备份项目案例
首先先写好备份的脚本(拷贝的命令) #bash/bin cd /finance/tomcat8-finance/wtpwebapps tar -czf /finance/webapp_backup/* ...
- 实验八 《Coderxiaoban团队》团队作业4:基于原型的团队项目需求调研与分析
实验八 <Coderxiaoban团队>团队作业4:基于原型的团队项目需求调研与分析 项目 内容 这个作业属于哪个课程 任课教师博客主页链接 这个作业的要求在哪里 实验八 团队作业4:基于 ...
- java项目部署到LIINUX
天领导给个任务,把java项目部署到liunx服务器上.现记录步骤,方便以后查看.项目部署服务器步骤:服务器信息:弹性IP地址:xx.xx.xxx.xx账号:root密码:cjw@100 数据库信息: ...
- LeetCode 1000. Minimum Cost to Merge Stones
原题链接在这里:https://leetcode.com/problems/minimum-cost-to-merge-stones/ 题目: There are N piles of stones ...
- java实现ssh登录linux服务器并下发命令
依赖jar包:jsch-0.1.55.jar commons-io-2.5.jar import com.jcraft.jsch.ChannelExec; import com.jcraft.js ...
- S1_搭建分布式OpenStack集群_03 Mysql、MQ、Memcached、ETCD安装配置
一.安装mysql(contorller)controller ~]# yum -y install mariadb mariadb-server python2-PyMySQL 配置my.cnf文件 ...
- B/S大附件上传,支持断点续传
核心原理: 该项目核心就是文件分块上传.前后端要高度配合,需要双方约定好一些数据,才能完成大文件分块,我们在项目中要重点解决的以下问题. * 如何分片: * 如何合成一个文件: * 中断了从哪个分片开 ...
- gerrit配置跳过审核直接push到gitlab
项目中有存放项目相关的文档,这些项目需要配置跳过审核再提交的操作.现在需要给某些组配置不审核直接提交的权限 方法: 使用管理员账号,到 projects -> access 页面下配置 refe ...