数据类型及转换

2016/01/03 Java

Java基础数据类型

Java是一种强类型的语言,针对每一种数据都定义了明确的数据类型。

数据类型分类:

A:基本数据类型
B:引用数据类型(类,接口,数组)

title

基本数据类型:4类8种

类型 占用字节数 表数范围
整数    
byte 1 -128~127
short 2 2^15~2^15-1
int 4 2^31~2^31-1
long 8 2^63~2^63-1
浮点数    
float 4 -3.403E38~3.403E38
double 8 -17.98E308~17.98E308
字符    
char 2  
布尔    
boolean 1 true,false

注意:

整数默认是int类型

byte,short在定义的时候,他们接收的其实是一个int类型的值。

这个是自己做了一个数据检测的,如果不再它们的范围内,就报错。

	128:10000000
	-128:10000000 (这里的1即是符号位,也是数值位)

浮点数默认是double类型。

长整型后缀用L或者l标记。建议使用L。

单精度浮点数用F或者f标记。建议使用F。

class DataTypeDemo{
	public static void main(String[] args) {
		//定义一个整型变量
		int i = 1000;
		//int j = 1000000000000;//超过了int的范围
		System.out.println(i);

		long j = 1000000000000L;
		//long j = 1000000000000;//这里超过了int的范围,long类型要加L
		System.out.println(j);

		//定义浮点数据变量
		float f = 12.345F;
		//float f = 12.345;//这里会提示精度丢失,默认为double类型,float类型要加F
		System.out.println(f);
	}
}

数据类型转换

默认转换

从小到大

byte,short,char – int – long – float – double

long: 8个字节

float:4个字节

A:它们底层的存储结构不同。

B:float表示的数据范围比long的范围要大

	long:2^63-1
	float:3.4*10^38 > 2*10^38 > 2*8^38 = 2*2^3^38 = 2*2^114 > 2^63-1

byte,short,char之间不相互转换,直接转成int类型参与运算。

class DataTypeDemo{
	public static void main(String[] args) {
		//定义一个byte类型,一个int类型,做加法
		byte a = 3;
		int b = 4;
		System.out.println(a + b);

		//byte c =  a + b;//可能损失精度
		int c = a + b;
		System.out.println(c);
	}
}

title

强制转换

从大到小

可能会有精度的损失,一般不建议这样使用。

格式:

目标数据类型 变量名 = (目标数据类型) (被转换的数据);

class DataTypeDemo{
	public static void main(String[] args) {
		byte a = 3;
		int b = 4;

		//byte c = a + b; //这个是有问题的

		byte c = (byte) (a + b);//用强制类型转换改进
		System.out.println(c);
	}
}

boolean类型不参与转换

思考题

思考题1:请问下面这个有没有问题

	double d = 12.345;
	float f = (float)d;//把double赋值给float,加了强制类型转换

思考题2:看看下面两个定义有没有区别呢?

	float f1 = (float)12.345;
	float f2 = 12.345f;

f1其实是通过一个double类型转换过来的。

而f2本身就是一个float类型。

面试题

哪句是编译失败的呢?为什么呢?

	byte b1=3,b2=4,b;
	b=b1+b2;//这个是类型提升,所有有问题。先转换成int类型,最后赋值也是int类型
	b=3+4;//常量,先把结果计算出来,然后看是否在byte的范围内,如果在就不报错。

b = b1 + b2;是有问题的。

因为变量相加,会首先看类型问题,最终把结果赋值的也会考虑类型问题。

常量相加,首先做加法,然后看结果是否在赋值的数据类型范围内,如果不是,才报错。

反编译的结果如下:

title

有没有问题?如果我想让赋值正确,可以怎么做?结果是多少呢?

	class DataTypeDemo{
		public static void main(String[] args) {
			//因为byte的范围是:-128到127。
			//而130不在此范围内,所以报错。
			//byte b = 130;

			//我们可以使用强制类型转换
			byte b = (byte) 130;

			//结果是多少呢?
			System.out.println(b);
		}
	}

分析过程:

我们要想知道结果是什么,就应该知道是如何进行计算的。

而我们又知道计算机中数据的运算都是补码进行的。

而要得到补码,首先要计算出数据的二进制。

1:获取130这个数据的二进制。

00000000 00000000 00000000 10000010
这是130的原码,也是反码,还是补码。

2:做截取操作,截成byte类型的了。

10000010
这个结果是补码。

3:已知补码求原码。

		符号位		数值位
补码:	1			0000010

反码:	1			0000001

原码:	1			1111110

结果:-126

字符参与运算

是查找ASCII里面的值

‘a’ 97

‘A’ 65

‘0’ 48

	System.out.println('a'+1); //98

Java语言中的字符char可以存储一个中文汉字吗?为什么呢?

可以。因为java语言中的字符占用两个字节。

Java语言采用的是Unicode编码。

title

之前的博客总结

http://www.cnblogs.com/songxp/p/4575122.html

Float存储结构延伸阅读

float类型数字在计算机中用4个字节存储。遵循IEEE-754格式标准:
	一个浮点数有2部分组成:底数m和指数e

底数部分 使用二进制数来表示此浮点数的实际值
指数部分 占用8bit的二进制数,可表示数值范围为0-255

但是指数可正可负,所以,IEEE规定,此处算出的次方必须减去127才是真正的指数。
	所以,float类型的指数可从-126到128

底数部分实际是占用24bit的一个值,但是最高位始终为1,所以,最高位省去不存储,在存储中占23bit
	科学计数法。

格式:
SEEE EEEE EMMM MMMM MMMM MMMM MMMM MMMM
S表示浮点数正负
E指数加上127后的值得二进制数据
M底数

举例:
17.625在内存中的存储

首先要把17.625换算成二进制:10001.101

	整数部分,除以2,直到商为0,余数反转。
	小数部分,乘以2,直到乘位0,进位顺序取。

在将10001.101右移,直到小数点前只剩1位:
	1.0001101 * 2^4 因为右移动了四位

这个时候,我们的底数和指数就出来了
底数:因为小数点前必为1,所以IEEE规定只记录小数点后的就好。所以,此处的底数为:0001101
指数:实际为4,必须加上127(转出的时候,减去127),所以为131。也就是10000011
符号部分是整数,所以是0
综上所述,17.625在内存中的存储格式是:
01000001 10001101 00000000 00000000

以上概念总结于传智播客Java基础课程

Search

    Post Directory