Skip to content

Commit 4e48e44

Browse files
committed
ss
1 parent 3abcfd4 commit 4e48e44

7 files changed

Lines changed: 448 additions & 2 deletions

File tree

src/com/yale/test/java/demo/Person.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,20 @@
11
package com.yale.test.java.demo;
22

3+
/**
4+
* 不写public,也能正确编译,但是这个类将无法从命令行执行。
5+
* 基本数据类型是CPU可以直接进行运算的类型。
6+
* Java定义的这些基本数据类型有什么区别呢?要了解这些区别,我们就必须简单了解一下计算机内存的基本结构。
7+
* 计算机内存的最小存储单元是字节(byte),一个字节就是一个8位二进制数,即8个bit。它的二进制表示范围从00000000~11111111,换算成十进制是0~255,换算成十六进制是00~ff。
8+
* 内存单元从0开始编号,称为内存地址。每个内存单元可以看作一间房间,内存地址就是门牌号。
9+
* 一个字节是1byte,1024字节是1K,1024K是1M,1024M是1G,1024G是1T。一个拥有4T内存的计算机的字节数量就是:
10+
* 对于整型类型,Java只定义了带符号的整型,因此,最高位的bit表示符号位(0表示正数,1表示负数)。各种整型能表示的最大范围如下:
11+
byte:-128 ~ 127
12+
short: -32768 ~ 32767
13+
int: -2147483648 ~ 2147483647
14+
long: -9223372036854775808 ~ 9223372036854775807
15+
* https://www.liaoxuefeng.com/wiki/1252599548343744/1255883729079552
16+
* @author dell
17+
*/
318
public class Person {
419
public static void main(String[] args) {
520
Person ps = new Person();

src/com/yale/test/math/BinaryTest.java

Lines changed: 75 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,81 @@ public static void main(String[] args) {
8585
System.out.println("位运算分为俩种:逻辑操作和位移操作:");
8686
System.out.println("逻辑操作就是一下几种: java运算符: &按位与,|按位或,^按位异域,~按位取反");
8787
System.out.println("位移操作就是一下几种: java运算符: <<左移, >>右移, >>>无符号右移");
88-
88+
/*
89+
* 移位运算
90+
在计算机中,整数总是以二进制的形式表示。例如,int类型的整数7使用4字节表示的二进制如下:
91+
00000000 0000000 0000000 00000111
92+
可以对整数进行移位运算。对整数7左移1位将得到整数14,左移两位将得到整数28:
93+
*/
94+
int n = 7; // 00000000 00000000 00000000 00000111 = 7
95+
int a = n << 1; // 00000000 00000000 00000000 00001110 = 14
96+
int b = n << 2; // 00000000 00000000 00000000 00011100 = 28
97+
int c = n << 28; // 01110000 00000000 00000000 00000000 = 1879048192
98+
int d = n << 29; // 11100000 00000000 00000000 00000000 = -536870912, 左移29位时,由于最高位变成1,因此结果变成了负数。
99+
100+
/*
101+
* 类似的,对整数28进行右移,结果如下:
102+
*/
103+
int nn = 7; // 00000000 00000000 00000000 00000111 = 7
104+
int aa = nn >> 1; // 00000000 00000000 00000000 00000011 = 3
105+
int bb = nn >> 2; // 00000000 00000000 00000000 00000001 = 1
106+
int cc = nn >> 3; // 00000000 00000000 00000000 00000000 = 0
107+
/**
108+
* 如果对一个负数进行右移,最高位的1不动,结果仍然是一个负数:
109+
* 有符号的右移应该前面是补1,所以这里是不是写错了?
110+
* 应该是写错了,查阅了一些资料,而且自己验证了一下,廖老师解释的不通。
111+
* 右移前面不是补1,第一位的0或1表示的是正负,使用>>的时候第一位是正负是不会移动的。不论左移还是右移空出来的位置都是补0.
112+
* 应该是写错了,试了一下10111000 00000000 00000000 00000000的结果并不是-134217728,11111000 00000000 00000000 00000000的结果才是
113+
* https://www.liaoxuefeng.com/wiki/1252599548343744/1255888634635520
114+
*/
115+
int nbb = -536870912;
116+
int abb = nbb >> 1; // 11110000 00000000 00000000 00000000 = -268435456
117+
int bbb = nbb >> 2; // 11111000 00000000 00000000 00000000 = -134217728
118+
int ccc = nbb >> 28; // 11111111 11111111 11111111 11111110 = -2
119+
int dcc = nbb >> 29; // 11111111 11111111 11111111 11111111 = -1
120+
121+
/*
122+
*还有一种不带符号的右移运算,使用>>>,它的特点是符号位跟着动,因此,对一个负数进行>>>右移,它会变成正数,原因是最高位的1变成了0:
123+
*/
124+
int ndd = -536870912;
125+
int add = ndd >>> 1; // 01110000 00000000 00000000 00000000 = 1879048192
126+
int bdd = ndd >>> 2; // 00111000 00000000 00000000 00000000 = 939524096
127+
int cdd = ndd >>> 29; // 00000000 00000000 00000000 00000111 = 7
128+
int ddd = ndd >>> 31; // 00000000 00000000 00000000 00000001 = 1
129+
//对byte和short类型进行移位时,会首先转换为int再进行位移。
130+
//仔细观察可发现,左移实际上就是不断地×2,右移实际上就是不断地÷2。
131+
132+
//对两个整数进行位运算,实际上就是按位对齐,然后依次对每一位进行运算。例如:
133+
int i = 167776589; // 00001010 00000000 00010001 01001101
134+
int nb = 167776512; // 00001010 00000000 00010001 00000000
135+
System.out.println(i & nb); // 167776512
136+
//上述按位与运算实际上可以看作两个整数表示的IP地址10.0.17.77和10.0.17.0,通过与运算,可以快速判断一个IP是否在给定的网段内。
137+
//牛客网练习题https://www.nowcoder.com/questionTerminal/34a597ee15eb4fa2b956f4c595f03218?f=discussion
138+
//码云 https://gitee.com/
139+
/*
140+
* 在Java的计算表达式中,运算优先级从高到低依次是:
141+
()
142+
! ~ ++ --
143+
* / %
144+
+ -
145+
<< >> >>>
146+
&
147+
|
148+
+= -= *= /=
149+
记不住也没关系,只需要加括号就可以保证运算的优先级正确。
150+
类型自动提升与强制转型
151+
在运算过程中,如果参与运算的两个数类型不一致,那么计算结果为较大类型的整型。例如,short和int计算,结果总是int,原因是short首先自动被转型为int:
152+
*/
153+
//也可以将结果强制转型,即将大范围的整数转型为小范围的整数。强制转型使用(类型),例如,将int强制转型为short:
154+
//要注意,超出范围的强制转型会得到错误的结果,原因是转型时,int的两个高位字节直接被扔掉,仅保留了低位的两个字节:因此,强制转型的结果很可能是错的。
155+
int i1 = 1234567;//整数运算的结果永远是精确的
156+
short s1 = (short) i1; // -10617
157+
System.out.println(s1);
158+
int i2 = 12345678;
159+
short s2 = (short) i2; // 24910
160+
System.out.println(s2);
161+
162+
89163
System.out.println("按位与运算:&,定义:参加运算的俩个数据,按二进制位进行‘于’运算,与运算:俩个数都为 1,则结果为1");
90164
System.out.println("&位与运算:1&1 = 1, 1&0 = 0, 0&1 =0, 0&0 = 0 ");
91165
System.out.println("示例:14&3即0000 1110 & 0000 0011 = 0000 0010 = 整数2,因此14&3=2,特点:①清零特定位②获取特定位");

src/com/yale/test/math/CharTest.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,5 +64,19 @@ public static void main(String[] args) {
6464
int num = 68;
6565
char c = (char)num;
6666
System.out.println("char可以将数字转换为英文字母" + c);
67+
68+
//字符类型char表示一个字符。Java的char类型除了可表示标准的ASCII外,还可以表示一个Unicode字符:
69+
char a = 'A';
70+
char zh = '中';
71+
System.out.println(a);
72+
System.out.println(zh);
73+
//字符类型char是基本数据类型,它是character的缩写。一个char保存一个Unicode字符:
74+
//因为Java在内存中总是使用Unicode表示字符,所以,一个英文字符和一个中文字符都用一个char类型表示,它们都占用两个字节。要显示一个字符的Unicode编码,只需将char类型直接赋值给int类型即可:
75+
int n1 = 'A'; // 字母“A”的Unicodde编码是65
76+
int n2 = '中'; // 汉字“中”的Unicode编码是20013
77+
//还可以直接用转义字符\\u+Unicode编码来表示一个字符:
78+
// 注意是十六进制:
79+
char c3 = '\u0041'; // 'A',因为十六进制0041 = 十进制65
80+
char c4 = '\u4e2d'; // '中',因为十六进制4e2d = 十进制20013
6781
}
6882
}
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
package com.yale.test.math;
2+
3+
/**
4+
* 不写public,也能正确编译,但是这个类将无法从命令行执行。
5+
* 基本数据类型是CPU可以直接进行运算的类型。
6+
* Java定义的这些基本数据类型有什么区别呢?要了解这些区别,我们就必须简单了解一下计算机内存的基本结构。
7+
* 计算机内存的最小存储单元是字节(byte),一个字节就是一个8位二进制数,即8个bit。它的二进制表示范围从00000000~11111111,换算成十进制是0~255,换算成十六进制是00~ff。
8+
* 内存单元从0开始编号,称为内存地址。每个内存单元可以看作一间房间,内存地址就是门牌号。
9+
* 一个字节是1byte,1024字节是1K,1024K是1M,1024M是1G,1024G是1T。一个拥有4T内存的计算机的字节数量就是:
10+
* 对于整型类型,Java只定义了带符号的整型,因此,最高位的bit表示符号位(0表示正数,1表示负数)。各种整型能表示的最大范围如下:
11+
byte:-128 ~ 127
12+
short: -32768 ~ 32767
13+
int: -2147483648 ~ 2147483647
14+
long: -9223372036854775808 ~ 9223372036854775807
15+
* https://www.liaoxuefeng.com/wiki/1252599548343744/1255883729079552
16+
* @author dell
17+
*/
18+
public class DataTypeDemo {
19+
20+
public static void main(String[] args) {
21+
/* 整数的数值表示不但是精确的,而且整数运算永远是精确的,即使是除法也是精确的,因为两个整数相除只能得到结果的整数部分:
22+
* 特别注意:整数的除法对于除数为0时运行时将报错,但编译不会报错。
23+
* 要特别注意,整数由于存在范围限制,如果计算结果超出了范围,就会产生溢出,而溢出不会出错,却会得到一个奇怪的结果:
24+
*/
25+
int i = 2147483647;
26+
int i2 = -2147483648;
27+
int i3 = 2_000_000_000; // 加下划线更容易识别
28+
System.out.println("加下划线也行:" + i3);
29+
int i4 = 0xff0000; // 十六进制表示的16711680
30+
int i5 = 0b1000000000; // 二进制表示的512
31+
long l = 9000000000000000000L; // long型的结尾需要加L
32+
33+
/*
34+
* 要解释上述结果,我们把整数2147483640和15换成二进制做加法:
35+
0111 1111 1111 1111 1111 1111 1111 1000
36+
+ 0000 0000 0000 0000 0000 0000 0000 1111
37+
-----------------------------------------
38+
1000 0000 0000 0000 0000 0000 0000 0111
39+
* 由于最高位计算结果为1,因此,加法结果变成了一个负数。
40+
* https://www.liaoxuefeng.com/wiki/1252599548343744/1255888634635520
41+
*/
42+
int x = 2147483640;
43+
int y = 15;
44+
int sum = x + y;
45+
System.out.println("奇怪的结果:" + sum); // -2147483641
46+
47+
/*
48+
* 注意++写在前面和后面计算结果是不同的,++n表示先加1再引用n,n++表示先引用n再加1。不建议把++运算混入到常规运算中,容易自己把自己搞懵了。
49+
*/
50+
int numC = 10;
51+
numC++;
52+
53+
/**
54+
* 浮点型
55+
* 浮点类型的数就是小数,因为小数用科学计数法表示的时候,小数点是可以“浮动”的,如1234.5可以表示成12.345x102,也可以表示成1.2345x103,所以称为浮点数。
56+
* 浮点数可表示的范围非常大,float类型可最大表示3.4x1038,而double类型可最大表示1.79x10308。
57+
*/
58+
float f1 = 3.14f;//对于float类型,需要加上f后缀。
59+
float f2 = 3.14e38f; // 科学计数法表示的3.14x10^38
60+
System.out.println("科学计数法的小数:" + f2);
61+
double d = 1.79e308;
62+
double d2 = -1.79e308;
63+
double d3 = 4.9e-324; // 科学计数法表示的4.9x10^-324
64+
65+
//Java语言对布尔类型的存储并没有做规定,因为理论上存储布尔类型只需要1 bit,但是通常JVM内部会把boolean表示为4字节整数。
66+
boolean is = true;
67+
68+
69+
//字符类型char表示一个字符。Java的char类型除了可表示标准的ASCII外,还可以表示一个Unicode字符:
70+
char a = 'A';
71+
char zh = '中';
72+
System.out.println(a);
73+
System.out.println(zh);
74+
75+
/* 除了上述基本类型的变量,剩下的都是引用类型。例如,引用类型最常用的就是String字符串:
76+
* 引用类型的变量类似于C语言的指针,它内部存储一个“地址”,指向某个对象在内存的位置,后续我们介绍类的概念时会详细讨论。
77+
* 常量的作用是用有意义的变量名来避免魔术数字(Magic number),例如,不要在代码中到处写3.14,而是定义一个常量。
78+
* 如果将来需要提高计算精度,我们只需要在常量的定义处修改,例如,改成3.1416,而不必在所有地方替换3.14。
79+
* 根据习惯,常量名通常全部大写。
80+
* jdk 14 增加var关键字
81+
* StringBuilder sb = new StringBuilder();可以换成 var sb = new StringBuilder();
82+
* 对编译器来说 实际上会自动变成:StringBuilder sb = new StringBuilder(); 因此,使用var定义变量,仅仅是少写了变量类型而已。
83+
*/
84+
}
85+
}
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
package com.yale.test.math;
2+
3+
public class FloatDemo {
4+
5+
public static void main(String[] args) {
6+
/*
7+
* 浮点数运算和整数运算相比,只能进行加减乘除这些数值计算,不能做位运算和移位运算。
8+
在计算机中,浮点数虽然表示的范围大,但是,浮点数有个非常重要的特点,就是浮点数常常无法精确表示。
9+
举个栗子:
10+
浮点数0.1在计算机中就无法精确表示,因为十进制的0.1换算成二进制是一个无限循环小数,很显然,无论使用float还是double,都只能存储一个0.1的近似值。但是,0.5这个浮点数又可以精确地表示。
11+
因为浮点数常常无法精确表示,因此,浮点数运算会产生误差:
12+
浮点数在内存的表示方法和整数比更加复杂。Java的浮点数完全遵循IEEE-754标准,这也是绝大多数计算机平台都支持的浮点数标准表示方法。
13+
*/
14+
double x = 1.0 / 10;//0.1
15+
double y = 1 - 9.0 / 10;//1-0.1
16+
// 观察x和y是否相等:
17+
System.out.println(x);
18+
System.out.println(y);
19+
float fn = 0.1f;
20+
System.out.println("浮点数0.1->" + fn);
21+
float res = (float)(1-0.9);
22+
System.out.println("float浮点数0.1->" + res);
23+
24+
double resd = (double)(1-0.9);
25+
System.out.println("double浮点数0.1->" + resd);
26+
//由于浮点数存在运算误差,所以比较两个浮点数是否相等常常会出现错误的结果。正确的比较方法是判断两个浮点数之差的绝对值是否小于一个很小的数:
27+
//比较x和y是否相等,先计算其差的绝对值:
28+
double r = Math.abs(x - y);
29+
// 再判断绝对值是否足够小:
30+
if (r < 0.00001) {
31+
// 可以认为相等
32+
System.out.println("相等");
33+
} else {
34+
// 不相等
35+
System.out.println("不相等");
36+
}
37+
38+
//如果参与运算的两个数其中一个是整型,那么整型可以自动提升到浮点型:
39+
int n = 5;
40+
double d = 1.2 + 24.0 / n; // 6.0
41+
System.out.println(d);
42+
43+
//需要特别注意,在一个复杂的四则运算中,两个整数的运算不会出现自动提升的情况。例如:
44+
double dd = 1.2 + 24 / 5; // 5.2
45+
//计算结果为5.2,原因是编译器计算24 / 5这个子表达式时,按两个整数进行运算,结果仍为整数4。
46+
47+
/*
48+
* 溢出
49+
整数运算在除数为0时会报错,而浮点数运算在除数为0时,不会报错,但会返回几个特殊值:
50+
NaN表示Not a Number
51+
Infinity表示无穷大
52+
-Infinity表示负无穷大
53+
*/
54+
55+
double d1 = 0.0 / 0; // NaN
56+
System.out.println(d1);
57+
System.out.println("Not a Number:" + Double.isNaN(d1));
58+
System.out.println("isInfinite:" + Double.isInfinite(d1));
59+
double d2 = 1.0 / 0; // Infinity
60+
System.out.println(d2);
61+
System.out.println("Not a Number:" + Double.isNaN(d2));
62+
System.out.println("isInfinite:" + Double.isInfinite(d2));
63+
double d3 = -1.0 / 0; // -Infinity
64+
System.out.println(d3);
65+
System.out.println("Not a Number:" + Double.isNaN(d3));
66+
System.out.println("isInfinite:" + Double.isInfinite(d3));
67+
/*
68+
* 强制转型
69+
* 可以将浮点数强制转型为整数。在转型时,浮点数的小数部分会被丢掉。如果转型后超过了整型能表示的最大范围,将返回整型的最大值。例如:
70+
*/
71+
int n1 = (int) 12.3; // 12
72+
int n2 = (int) 12.7; // 12
73+
int n22 = (int) -12.7; // -12
74+
int n3 = (int) (12.7 + 0.5); // 13
75+
int n4 = (int) 1.2e20; // 2147483647
76+
77+
//如果要进行四舍五入,可以对浮点数加上0.5再强制转型:
78+
double ddd = 2.6;
79+
int ndd = (int) (ddd + 0.5);
80+
System.out.println("如果要进行四舍五入,可以对浮点数加上0.5再强制转型:" + ndd);
81+
/*
82+
* 廖雪峰的练习题
83+
* 计算前N个自然数的和可以根据公示:
84+
(1+N)×N2\frac{(1+N)\times N}22(1+N)×N​
85+
请根据公式计算前N个自然数的和:
86+
https://www.liaoxuefeng.com/wiki/1252599548343744/1255888634635520
87+
* 根据一元二次方程ax2+bx+c=0ax^2+bx+c=0ax2+bx+c=0的求根公式:
88+
−b±b2−4ac2a\frac{\displaystyle-b\pm\sqrt{b^2-4ac}}{\displaystyle2a}2a−b±b2−4ac
89+
计算出一元二次方程的两个解:
90+
https://www.liaoxuefeng.com/wiki/1252599548343744/1255887847679616
91+
请将一组int值视为字符的Unicode编码,然后将它们拼成一个字符串:
92+
https://www.liaoxuefeng.com/wiki/1252599548343744/1255938912141568
93+
*/
94+
95+
int nx = -100;
96+
int xb = nx >= 0 ? nx : -nx;//上述语句的意思是,判断n >= 0是否成立,如果为true,则返回n,否则返回-n。这实际上是一个求绝对值的表达式。
97+
System.out.println(xb);
98+
}
99+
}

0 commit comments

Comments
 (0)