没有使用strictfp
正如我们所熟知的那样,java分为八大基本数据类型,分别是:
整数类型:byte(1) short(2) int(4) long(8)
浮点类型:float(4) double(8)
字符类型:char
布尔类型:boolean(true|false)
ps:小容量的数据在计算时,jvm会将其自动转为大容量数据,而大容量数据要转为小容量的数据,需要我们手动去转型。
其他的全部为引用类型:String类,数组,自定义类
大容量的数据类型可以转化为小容量的数据类型时,需要在前面加上强制类型转化符, 否则,java虚拟机会自动捕捉这种错误(这就涉及到error和exception的区别),但 在转换的过程中,容易造成数据的失真
Java虚拟机会自动将小容量的数据类型转化为大容量的数据类型时
转型顺序为:short,byte,char–>int–>long–>float–>–>double
short,byte,char之间不能转换
浮点型的默认类型:double
整数的默认类型: int
public class Test1 {
public static void main(String[] args){
testWithoutStrictfp();
//steictfpTest();
}
/**
*
* 正如我们所熟知的那样,java分为八大基本数据类型,分别是:<br/>
* 整数类型:byte(1) short(2) int(4) long(8)
* <br> 浮点类型:float(4) double(8)
* <br> 字符类型:char
* <br> 布尔类型:boolean(true|false)
*
* <br>其他的全部为引用类型:String类,数组,自定义类
*
* <br>大容量的数据类型可以转化为小容量的数据类型时,需要在前面加上强制类型转化符
* 否则,java虚拟机会自动捕捉这种错误(这就涉及到error和exception的区别),但
* 在转换的过程中,容易造成数据的失真
*
* <br>Java虚拟机会自动将小容量的数据类型转化为大容量的数据类型时
* 转型顺序为:short,byte,char-->int-->long-->float-->-->double
*
* short,byte,char之间不能转换
*
* <br>浮点型的默认类型:double
* <br>整数的默认类型: int
*
* 原子性:一个事务或多个事务要么同时提交而不受任何因素的干扰,要么就不提交
* 有序性
* 可见性
*
* @auhtor 念兮
*
*/
private static void testWithoutStrictfp(){
int i=10; //因为整形的数据类型,默认为int
int j=8;
System.out.println("i+j的数值为:"+(i+j));
//因为是double类型,Java虚拟机将其默认地转型
//因而,数据会出现失真
double ijd=(i+j)*1.2;
System.out.println(ijd);
/**
* 因为是float浮点类型,Java虚拟机为发将其转型为float类类型
* 因而,我们需要将其手动转型
*/
float ijf=(float)((i+j)*1.2);
System.out.println(ijf);
/**
* ijd的输出结果为:21.599999999999998
* ijf的输出结果为:21.6
* 因而,在数据进行转型的时候,就出现了数据的不一致
*
* 怎么才能保证不失真呢,我们就需要用到strictfp这个保留字,
* 它是script float potion 精准浮点,完全符合IEEE 754标准的
* IEEE745规定了硬件的数据的准确性,保罗单精度浮点数,和双精度浮点数
* 但它只能修饰类、接口、方法,不能修饰局部变量和成员变量
*/
/**
* 这样也是报错,因为浮点数默认的是double,而不是float
* 因而需要转型,即在10.0后面加上F/f
*/
float f1=10;
/**
* 输出结果并不是10,而是10.0
*/
System.out.println("f1"+f1);
float f2=10.0F;
System.out.println("f2:"+f2);
double strictfp_ijd=(i+j)*1.2;
System.out.println(strictfp_ijd);
float strictfp_ijf=(float)((i+j)*1.2);
System.out.println(strictfp_ijf);
System.out.println("f1/strictfp_ijf:"+f1/strictfp_ijf);
System.out.println("f2/strictfp_ijf:"+f2/strictfp_ijf);
short s1=10;
/**
* 这样就会报错,因为s1+1的结果类型不再是short,而是自动转型为int
* 这是需要将大类型的int转换为小类型的short,
*/
s1=(short)(s1+1);
System.out.println(s1);
/**
* 但是 s1++就不会出现错误
*/
System.out.println(s1++);
/**
* byte 2^-8~2^8-1 即-128-127
*/
byte byte1=23;
byte byte2=24;
/**
* 这样也会报错,因为byte1+byte2时,java虚拟机将其的类型转化为int了
* 如果,我们想要获取类型为byte的结果,就必须将其转型
* 但有一个重要的方法,它的输出结果为23,难道只输出了byte1吗?
*
* 答案是错误的,首先我们来了解byte这个基本数据类型,byte是字节类型的,
* 它的取值范围是-128~127之间,占位是256位,也就是说,这是一个循环,
* 我们全部将其转化为二进制(利用windows自带的计算器):
* 23为10111<br>
* 24为11000<br>
* 1000为1111101000
* 对其进行二进制的加法可得:10000010111,
* 而byte是八位的,因而只取00010111
* 首位是符号位,0表示正,1表示负
* 将其转化为十进制为:结果正好为23
* 因为,所有的代码在内存中都是二进制,即0和1表示
* 这是原码的加法,计算器组成原理的知识点
*
* 这也就是黑客帝国中的二进制代码的看点
*/
byte byte3=(byte)(byte1+byte2+1000);
System.out.println("byte:"+byte3);
/**
* 如果我们赋值的结果是100000000000000000000000,那么就会报错
* 因为l的长度是:-2^63-2^63-1,这远远超过了长度
*
* 但问几遍我们写成这样:10000000000000000,没有超过长度,依然会报错
* 因为,Java虚拟机的整形数据类型默认为int,而这确实long类型,当然会报错
* 一般我们在末尾加上L/l,我们一般不用小写的l,因而这看起来其极像阿拉伯数字1
* 因而,我们一般写成为L;
*/
long l1=10000000000L;
long l2=(long)1E10; //用科学计数法需要转型
double d1=l1+l2;
/**
* 输出结果为:2.0E18 采用的科学计数法,因为是double类型的浮点数
*
* “aEb”所表示的值是a × 10b E/e表示10,b表示指数
* 但我们国家一般要求科学计数法不是这样的,可以参见:
* GB3101-1993,GBT15835-2011,GBT8170-2008
* 而是a*10b;
*/
System.out.println(d1);
/**
* float fd=d1/l1;这是会报错的,因为需要进行转型
*/
float fd=(float)d1/l1;
System.out.println(fd);
float f4=10000000.6F; //转型时,符合四舍五入的方法,满6才进1
float f5=10000000.5F;
long l4=(long)f4;
long l5=(long)f5;
System.out.println(l4);
System.out.println(l5);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
使用strictfp
如果想要精度更加准确,而且不会因为硬件的改变而失真, 我们可以用strictfp来修饰。它是script float potion 精准浮点,完全符合IEEE 754标准的。 IEEE745规定了硬件的数据的准确性,包括单精度浮点数,和双精度浮点数。但它只能修饰类、接口、方法,不能修饰局部变量和成员变量
private static strictfp void steictfpTest(){
int i=10; //因为整形的数据类型,默认为int
int j=8;
float f=10.0f;
double strictfp_ijd=(i+j)*1.2;
System.out.println(strictfp_ijd);
float strictfp_ijf=(float)((i+j)*1.2);
System.out.println(strictfp_ijf);
System.out.println(f/strictfp_ijf);
System.out.println(System.class);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
i++和++i的区别
private static void testPlusPlus(){
int i,i1=20;
/**
* 这种表示i先获得i1++的数值,然后i1在自行加1
*
* 换句话说,i1把初始值赋给i后,i1再自行加1
*/
i=i1++;
System.out.println("i的数值:"+i+"\ti1的数值:"+i1);
/**
* 这种方式表示,i先进行加1的计算,再把值赋给i;
*/
i=++i1;
System.out.println("i的数值:"+i+"\ti1的数值:"+i1);
}
---------------------
【转载】
作者:念兮为美
原文:https://blog.csdn.net/lvoelife/a ... 980?utm_source=copy
|
|