一、进制
1.1 进制的区分
1.2进制的换算
只要掌握计算器的方式即可。人工计算的方式了解一下就行了。
二、计算机数据的存储原理
2.1 存储单位
最小的单位:比特位 bit 1位比特要么为0,要么为1
最基本的单位:字节 byte 1个字节=8位
1个字节:1B(B=1byte)
1KB=1024B
1MB=1024KB
1GB=1024MB
1TB=1024GB
1PB=1024TB
2.2 Java的八种数据类型
整数类型:
byte 1个字节 取值范围:2^-7——2^7-1
short 2个字节 取值范围:2^-15——2^15-1
int 4个字节 取值范围:2^-31——2^31-1
long 8个字节 取值范围:2^-61——2^61-1
小数类型:
flot 4个字节
double 8个字节
字符类型:
char 4个字节
布尔类型:
boolean 1个字节
如下图所示:
2.3 符号位
规定:
用0表示正数,1表示负数
二进制中最高位(最左位)就是符号位
符号位针对于byte,short,int.long,flot,double这些类型而言
2.3 原码、反码、补码
00000100 => 4
10000100 => -44 + (-4)00000100+ 10000100----------10001000 => -8 ? 不对
因为我们不仅仅要表示数字,还得考虑正、负数的计算问题,所以需要设计新的规则,便于存储和计算,这个时候就提出了原码、反码、补码。
计算机的底层存储和计算都是基于补码的。规定:
-
正数:原码、反码、补码都一样,三码合一
-
负数:
-
原码:最高位是1,其余位是数据位,这些数据位与其绝对值的二进制序列是一样的
-
反码:最高位不变,其余位在原码的基础上取反(0变1,1变0)
-
补码:在反码的基础上 + 1
-
正数的25:+25原码:00011001反码:00011001补码:00011001负数的25:-25原码:10011001反码:11100110补码:11100111
2.4 整数如何存储(以byte为例)
问题:1个字节可以存储的整数范围是什么?
结论:-128 ~ 127
正数:0000 0001 对应十进制的1....0111 1111 对应的十进制127负数:1000 0001 对应的十进制-127....1111 1111 对应的十进制-1补码:1000 0001反码:1000 0000原码:1111 1111补码:1111 1111反码:1111 1110原码:1000 0001零:0000 0000 对应十进制的01000 0000 对应十进制的-128(特殊的规定)用它来表示-128,既要符合计算的规则,又要符合数据表示的规则。-127 - 1 = -128-127的补码:1000 00011的补码:0000 00011000 00010000 0001-=========1000 0000
注意:从二进制->十进制,用权值相加法,需要用原码计算
2.5 小数如何存储
(1)无论是flot或double,都是浮点类型,在存储时都是不精确、都有误差的
(2)flot一般在小数点后最多7-8位。 double一般在小数点后最多15-16位
(3)flot虽然是4个字节但是因为存储方式的不同,它的范围比long大的多
2.6 char类型如何存储
因为计算机里面只有二进制,所以所有的文字、标点符号等也必须用一个二进制值表示。为了统一,就有一些组织就规定了每一个字符对应哪个二进制值,这个对应表被称为字符集。
最古老的字符集是ASCII码字符集,这个字符集中值规定了0-127,共128个字符。
常见的ASCII码字符集
'a':97 'b':98
'A':65 'B':66
'0':48 '1':49
'\t':9 ' ':32
char类型的表示方式有3种:
-
'涣'
-
28067
-
'\u6da3';
三、基本数据类型的转换
3.1 自动类型转换(小转大)
(1)当把数据类型较小的值赋值给较大的数据类型时,就会自动提升
(2)当对byte、short、char 进行计算的时候,他们的数据类型就会自动转为int
(3)当有多种数据类型的值进行混合运算的时候,取其中最大的数据类型
三种情况依次如下图所示:
package com.yang;/*** @author yzh* @date 2024/07/17*/public class Test05 {public static void main(String[] args) {char a ='啊';int b=a;System.out.println(b);}
}
package com.yang;/*** @author yzh* @date 2024/07/17*/public class Test05 {public static void main(String[] args) {byte a =6;byte b=1;System.out.println(a+b);int i = a + b;System.out.println(i);}
}
package com.yang;/*** @author yzh* @date 2024/07/17*/public class Test05 {public static void main(String[] args) {byte a = 6;int b = 1;long c = 15L;float d = 5.3f;double e = 1.39;System.out.println(a + b + c + d + e);double v = a + b + c + d + e;System.out.println(i);}
}
3.2 强制数据类型转换(大转小)
(1)当我们把一个较小的数据类型赋值给一个较大的数据类型的时候,就要使用强制数据类型转换,但是此时可能出现损失精度或溢出的风险。
(2)当我们需要故意提升一个值(常量值,变量值,表达式的结果值) 的类型的时候,也需要强制数据类型转换。
两种情况依次如下图所示:
package com.yang;/*** @author yzh* @date 2024/07/17*/public class Test05 {public static void main(String[] args) {double d = 3.14;int num = (int)d;System.out.println(d);//3.14System.out.println(num);//3int big = 200;byte b = (byte)big;System.out.println(big);//200System.out.println(b);//-56/*200的二进制 00000000 00000000 00000000 11001000(byte)截断 11001000补码:11001000(如果是计算器看结果,直接用它即可)反码:11000111原码:10111000(人工权值相加法,需要看原码)*/}
}
package com.yang;/*** @author yzh* @date 2024/07/17*/public class Test05 {public static void main(String[] args) {int x = 1;int y = 2;System.out.println(x/y);//0//int / int 结果还是 int//如果希望结果是double类型,在不改变x,y变量类型前提下,怎么办?System.out.println((double)x/y);//0.5//取x的值1之后,将1强制提升为double类型的1.0,然后与y进行计算,double/int结果是doubleSystem.out.println((double)(x/y));//0.0//先计算x/y,然后结果0再提升为doubleboolean b = false;//System.out.println((int)b);//Java中不允许}
}
四、运算符
4.1 算术运算符
例题:定义一个变量,赋值为一个四位数整数,例如1234,如通过运算操作求出个位,十位,百位,千位
package com.yang;import java.util.Scanner;/*** @author yzh* @date 2024/07/17*/public class Test05 {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);System.out.print("请输入一个四位的正整数:");int i = scanner.nextInt();System.out.println("个位上的数为:"+i%10);System.out.println("十位上的数为:"+i/10%10);System.out.println("百位上的数为:"+i/100%10);
// System.out.println("千位上的数为:"+i/1000);也可System.out.println("千位上的数为:"+i/1000%10);}
}
4.2 会改变变量值的运算符
4.2.1 赋值运算符
4.2.2 自增自减运算符
自增自减运算符本身属于算术运算符。
情况一:自增自减表达式是独立的语句
自增自减在前在后没有区别。++a;与 a++;相同, --a; 与 a--;相同
情况二:自增自减表达式不是独立的语句
以自增为例: ++在前:先对变量自增1,然后取自增变量的值做其他运算 ++在后:先取自增变量的值放一边,然后自增变量自增1,用刚刚取出来的值做其他运算
如:
package com.yang;/*** @author yzh* @date 2024/07/17*/public class Test05 {public static void main(String[] args) {int i = 1;int j = i++; //j=1 , i=2int k = i++ * ++j + ++i * j++; // 2*2+ 4*2 =12 i = 4 , j =3System.out.println("i = " + i);System.out.println("j = " + j);System.out.println("k = " + k);}
}
4.2.3 关系运算符
关系运算符是用于比较两个值的大小关系。所有关系运算符的运算结果只有两种:true或false。
4.2.4 逻辑运算符
逻辑运算符是用于表示两个条件的关系。
逻辑与:&用于表示两个条件必须“同时”成立。true & true 结果truetrue & false 结果falsefalse & true 结果falsefalse & false 结果false逻辑或:|用于表示两个条件只要有1个成立就行。true | true 结果truetrue | false 结果truefalse | true 结果truefalse | false 结果false逻辑异或:^用于表示两个条件只能成立1个。不能同时成立,也不能同时不成立。即两个条件的结果必须不同。true ^ true 结果falsetrue ^ false 结果truefalse ^ true 结果truefalse ^ false 结果false逻辑非:!对一个条件取反!true 结果false!false 结果true短路与:&&用于表示两个条件必须“同时”成立。true && true 结果truetrue && false 结果falsefalse && true 结果falsefalse && false 结果false&&的效率比&高。因为当左边为false时,右边就不看了。短路或:||用于表示两个条件只要有1个成立就行。true || true 结果truetrue || false 结果truefalse || true 结果truefalse || false 结果false||的效率比|高。因为||当左边为true时,右边就不看了。
4.2.5 条件运算符
如:
package com.yang;/*** @author yzh* @date 2024/07/17*/import java.util.Scanner;/*** 声明一个int类型的变量year,赋值为当年的年份值,判断该年是否是闰年,输出判断结果。* 闰年的判断标准是:* (1)年份year可以被4整除,但不能被100整除* (2)或年份year可以被400整除*/
public class Test04 {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);System.out.print("请输入年份:");int year = scanner.nextInt();System.out.println(((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) ? "闰年" : "非闰年");}
}