二进制以0b开头,八进制以0开头,整数默认为十进制,十六进制以0x开头0-9,a-f(大小写均可)
不同进制的数据表现:
二进制:由0,1组成,以0b开头
八进制:由0-7组成,以0开头
十进制:由0-9组成,默整数为十进制
十六进制:有0-9,a-f(大小写均可)组成,以0x开头
- 其他进制到十进制的转换:
十进制-->十进制:12345=10000+2000+300+40+5
=1*10^4 + 2*10^3 + 3*10^2 + 4*10^1 + 5*10^0
系数:每一个位上的数据本身就是系数
基数:x进制的数那么它的基数就是x
权: 我们针对每一个上的数据进行编号,从右边到左,并且从0开始编号,这个编号就是该位上数据的权值。
每个位上的 系数*基数^权次幂 相加的和 就是进制转换后的结果
二进制-->十进制:1011 = 1*2^3 + 0*2^2 + 1*2^1 + 1*2^0 = 8+0+2+1 = 11
- 十进制转到其他进制:
十进制12345转到十进制,一直除以10取余,直到商为零,余数反转即可。
所以同理对于整数十进制转到其他进制则是“除基取余,到商为零,余数反转”!
举例:我们把十进制的数76分别转为二、八、十六进制如下:
但是小数:“一直取小数部分乘以基数提取整数部分,直到小数部分为0,取整数正序排列”
举例:我们对把十进制的带小数的 76.125 转换为二进制数 如下:
0.125 * 2 = 0.25-------取整数部分 0
0.25 * 2 = 0.5---------取整数部分 0
0.5 * 2 = 1.0---------取整数部分 1
此时小数部分已经是0,将所取的整数部分正序排列:001
76在上方已经变为二进制数为:1001100
所以76.125对应的二进制数为:1001100.001
- 8421码
1 1 1 1 1 1 1 1
128 64 32 16 8 4 2 1
0b1010100=1*2^6+1*2^4+1*2^2=84
100=0b1100100
(100之内最高到64没有128)-0 (有64)-1
(100-64=36有32)----------------------------1
(36-32=4没有16)-----------------------------0
(4没有8)----------------------------------------0
(4有4)-------------------------------------------1
(4-4=0没有2)----------------------------------0
(0没有1)----------------------------------------0
所以综上所述:01100100,最左边的零可以省去可得二进制0b1100100=十进制100
以小数点分左右两界,
左边从左到右进行8421码,右边则是系数*基数^(-n),n是指以小数点为界向右数第几位。
- 二进制数0b1011001转换为八进制、十六进制
二进制到十进制再到八进制、十六进制
方式一:0b1011001=1*2^0+1*2^3+1*2^4+1*2^6=1+8+16+64=89
89=0131
89/8=11……1
11/8=1…….3
1/8=0….…1
方式二:0b1011001(二转八:从右往左数,三个为一组,不足再补零,转化十进制,最后再组体)
【二转十六进制则从小数点划分左右取四个为一组,不足补零】
001 011 001
001=1
011=3
001=1
所以 1011001(二进制)=0131(八进制)
1001=9
0101=5
所以 1011001(二进制)=59(十六进制)
- 有符号数据的表示法:
举例7和-7来探索:原码,反码,补码。
二进制 的补码来计算的。0表示“正”,1表示“负”。
******原码:正数的原码最高位是0,负数的原码最高位为1。
一个字节来存储符号所以占到八位(符号位+数值位),要在数值位左面补零
7:符号位:0 数值位:111----0000111
-7:符号位:1 数值位:111----1000111
******反码:正数的反码和原码相同;负数的反码是原码的符号位不变,数值位取反(1变零,0变1)。
7:0 0000111
-7:1 1111000
******补码:正数的补码与原码相同;负数的补码是反码的末尾“加1”(1+1=0,前位进1,直到遇0成1为止)。
7:0 0000111
-7:1 1111001
- 常量的输出:
System.out.println("hello"); /*字符串的输出一定要用两个双引号*/
System.out.println(100.10); /*整数与小数常量的输出直接输出*/
System.out.println('a'); /*单个字符则使用单引号*/
System.out.println('ab');
/*此处会报错,因为系统检测出单引号内并非一个字符,所以认为单引号是双引号没有写完*/
System.out.println(true); /*布尔常量只有两种的输出,正确与错误 true 或 false*/
- 数据类型的强制转换:
基本的数据类型:4类8种:
A: 整数 占用字节数
byte 1
short 2
int 4(整数默认类型)
long 8(在定义long值后面加l或L,以作标记,给计算机以提示:long j=1000000L;)
B:浮点数
float 4(同理long在后面加对应的f或F,以作标记:float f=12.345F;)
double 8(浮点数默认类型)
C:字符
char 2
D:布尔
boolean 1
从大的数据类型到小的数据类型
目标数据类型 变量=(目标数据类型)(被转换的数据);
byte a=3;
int b=4;
byte c=a+b; /* (×) */
byte c=(byte)(a+b); /* (√) */
如果double d=12.345; float f=d;则将会损失精度而报错
double d=12.345;
float f=(float)d; /* (√) */
float f1=12.345F; /* (√)建议这种转换! */
/*
*【f是由double转换到float;而f1则本身就定义为了float类型。】
*float f1=(float)12.345;【浮点型的数本身默认为double类型,这里转换成了float类型】
*float f2=12.345f;【直接就12.345这个数定义为float类型,不做转换】
*/
byte b1=3,b2=4,b;
b=b1+b2; /* × */
b=3+4; /* √ */
【已经定义b1,b2,b为byte类型,而b1+b2之间的运算会先将其所代表的值转为int类型进行运算,所以结果也会是int类型,又要将int类型结果赋给byte类型的b,就像是国王的孩子被安排到穷乡僻壤取生活,怎能屈尊寒地?系统报错类型的提升!】
【变量相加,会首先看类型的问题,最终的结果赋值也会考虑类型问题。】
【常量相加,先做加法,然后看结果是否在赋值的数据类型范围内,如果不是,才报错。】
class demo
{
public static void main(String[] args){
byte a=130; /* 单取变量值130会被当作int类型 */
System.out.println(a); /*错误: 不兼容的类型: 从int转换到byte可能会有损失 因为byte最大到 127 */
byte b=(byte)130; /* 将130由int类型转为byte类型 */
System.out.println(b); /* 输出 -126 */
}
/*
130已经超出了byte的范围,报错!
计算机中的数据是以补码进行运算的,想要得到补码,首先要有数据的二进制。
单写130默认为int类型对应4个字节=4*8=32位,数值位左面补0。
00000000 00000000 00000000 10000010是原码,反码,也是补码
截取操作,截成byte类型
byte类型对应1个字节=8位,所以只保留数值位足矣
10000010是补码,因为操作过程是补码,可以看到符号位也就是首位是1所以是负数
此时的数值位在byte中是数值位与符号位共存体
已知负数的补码求原码:补码+1=反码;反码”数值位按位取反“=原码
符号位 数值位
补码: 1 0000010
反码: 1 0000001
原码: 1 1111110------(-126)
所以最终结果为-126
*/
}
- 字符与一个整数相加,对应ASCII码的运算值。
'a' 97
'A' 65
'0' 48
System.out.println('a');表示直接输出一个字符
System.out.println('a'+1);表示输出一个字符和一个整数做加法,是此字符的ASCII码加数字,此处为98
- 字符串数据和其他数据做+,结果是字符串类型。
这里的+不再是加法运算,而是字符串连接符。连接时注意“从左到右”的原则。
System.out.println("hello"+'a'+1);/* helloa1 */
System.out.println('a'+"hello");/* ahello */
System.out.println("5+5="+5+5);/* 5+5=55 */
System.out.println(5+5+"=5+5");/* 10=5+5 */
- 在定义Long或者Float类型变量的时候,要加L或F,整数默认为int类型,浮点数默认是double
byte,short在定义的时候,他们接收的其实是一个int类型的值。会有自动检测,如果不在它们的范围内,就会报错。
byte值得问题:byte b1=127;
byte b2=(byte)128;//-128
byte b3=(byte)129;//-127
byte b4=(byte)130;//-126
byte的范围:-128到127 如果超出了范围,所得数值就进行一个逆轮回
之所以byte128=-128,是以为如下:
128:10000000
-128:10000000(这里的1既是符号位,也是数值位)
- 数据类型转换之默认转换或参与运算时的转换
byte,short,char--> int --> long --> float --> double
long:8个字节 float:4个字节 为什么long会在float之下呢?
A:它们的底层存储结构不同。
B:float表示的数据范围比long的范围要大
各自的最大值:long: 2^63-1 float: 3.4*10^38
3.4*10^38 > 2*10^38 > 2*8^38 = 2*2^3^38 = 2*2^114 > 2^63-1
问题:
Java语言中的字符char可以存储一个中文汉字吗?为什么?
可以,因为java语言中的字符占用两个字节,并且java语言采用的是Unicode编码。
- 使用变量是候要注意的问题:
A:作用域
变量定义在哪个大括号内,它就在这个大括号内有效。
并且,在同一个大括号内不能同时定义同名的变量;
B:初始化值
没有初始化值的变量不能直接使用。
只要在使用前给值就行,不一定非要在定义的时候立即给值。
推荐在定义的时候给值。
- +是一个运算符,做加法运算。
一般来说,我们在运算的时候,要求参与运算的数据类型必须一致。
注意:
boolean类型不能转换为其他的数据类型
默认转换(从小到大的转换)
byte,short,char-int-long-float-double
byte,short,char互相之间不转换,他们参与运算首先转换为int类型。
【--------计算机进行运算时会换成数字所对应的补码--------】·
byte a=4;
int b=4;
System.out.println(a+b);/* 【正确】*/
byte a=4;
int b=4;
byte c=a+b;
System.out.println(c);
/* 【错误;因为加减运算会先转换为int类型,而c是byte类型,但是a+b的结果却是int类型;所以会损失精度。】 */
- 整数相除只保留整数部分,如果想要保留小数,只需要将操作数的数据中的任意的一个数据变为浮点数。
class demo
{
public static void main(String[] args)
{
int x=3,y=4;
System.out.println(x/y); /* 0 */
System.out.println(x*1.0/y); /* 0.75 */
}
}
%表示取余,得到的是余数。
- ++,--
a++,++a。如果上面的语句中出现了a++,无论自主还是被赋值,只要是出现了,那么就会进行一次"加1"运算,所以自身的值已经更新了。在赋值语句中,加加减减在后,则会把原值先赋给变量,然后再进行自身的加减。如果加加减减在前,在紧接着的运算中则是自身自加自减的结果参与运算而不再是原值。
例:
int r=4;
int t=(r++)+(++r)+(r*10);
/*其实t= 4 + 6 + 6*10 */
/*
* r++:虽然进行了加一运算,但是参与运算的r的值是4。
* 注意:因为已经进行了”加1“运算,所以实际的r的值是5。
* ++r:加加在前,则是先进行加一运算之后出结果参与运算,此时r的实际值是6,直接参与后面的运算
*/
面试题:【short s=1,s=s+1;】和【short s=1,s+=1;】哪个有问题?
第一个有问题,第二个没问题。
注意:第二个扩展的赋值运算符其实隐含了一个强制类型转换。
s+=1;并非等价于s=s+1;而是等价于s=(s的数据类型)(s+1);s+1运算时虽然是int类型,但是内部做了类型转换处理。
s=s+1;会损失精度,因为s+1的运算会先转换为int类型,而最终赋值的s却是short类型,所以报错。
- +=把左边和右边做加法,然后赋值给左边。左边必须是变量。
- "=="表示等于,"="表示赋值,两者不同。
在比较运算符:==,!,=,<,>,>=,<=参与的操作中,无论是简单还是复杂,结果都是boolean类型,且布尔类型只有两种,正确与否即true,false
例如:
int a=10,b=20;
boolean flag=(a==b); /* 用flag来表示判断a等于b的结果 */
boolean flag=(a=b); /* 把b的值赋给a也是int类型,而int类型又赋值给boolean,这是不兼容的问题 */
System.out.println(flag); /* false */
int c=(a=b); /* 指把b赋值给a,然后把a留下来。所以c的是b传给a的20 */
- 逻辑运算符:&,|,^,!,&&,||
逻辑运算符一般是boolean类型的表达式或值。
表达式:就是用运算符把常量或者变量连接起来的符合java语法的式子。算数表达式:a+b,比较运算符:a==b
逻辑与:&:有false则false
逻辑或:|:有true则true
逻辑异或:相同为false,不同则true
逻辑非:!:非false则true,非true则false(偶数个不改变本身)
int a=3,b=4,c=5;
System.out.println((a>b)^(a>c));//false ^ false------false
System.out.println((a>b)^(a<c));//false ^ true------true
System.out.println((a<b)^(a>c));//true ^ false------true
System.out.println((a<b)^(a<c));//true ^ true------false
当()内&,|,^,~两边是数据则是位运算,当其两边是boolean值则是逻辑运算。
- &&与&的区别;|| 与 | 的区别
&&效果,左边是false,右边不执行;见错即错
|| 效果,左边是true ,右边不执行;见对则对
而& 和 | 属于位运算符
- 位运算符:&,|,^,~,<<,>>,>>>
注意:要做位运算,首先要把数据转换为二进制。
例子1:
int a=3,b=4;
System.out.println(3&4);
//3的二进制:11 4的二进制:100
//3:00000000 00000000 00000000 00000011
//4:00000000 00000000 00000000 00000100
//&位运算:有0则0
结果:00000000 00000000 00000000 00000000--0
例子2:
System.out.println(3|4);
// | 位运算:有1则1
结果:00000000 00000000 00000000 00000111--7
例子3:
System.out.println(3^4);
//^位运算:相同则0,不同则1
结果:00000000 00000000 000000000 00000111--7
例子4:
System.out.println(~3);
//~位运算:0变1,1变0
00000000 00000000 00000000 00000011
~11111111 11111111 11111111 11111100(补码)
11111111 11111111 11111111 11111011(反码--负数的补码是反码+1,所以其反码也就是补码-1)
10000000 00000000 00000000 00000100(原码)--(-4)
结果是:-4
【算术运算对象与结果在机器内部都是以补码的形式存储的,只是在输出的时候以原码呈现,即在输出时还原成原码】