Java 2:8种数据类型

这一块尤其是浮点数部分比较乱,《Java核心技术》写的太简略,参考的博客资料有些地方有冲突,但感觉主要理解其思想概念,具体的细节、精确度其实不用太在意。

最详细,看上去比较靠谱的是http://hujiantao224.iteye.com/blog/727155,不过太详细本渣都懒得看完了

当然最好的还是去看IEEE 754规范


Java是一种强类型语言,必须为每一个变量声明一个类型

一共8种基本类型:4种整型、2种浮点、一种布尔、一种字符(Char表示Unicode编码的字符单元)

Java为了解决平台移植问题,整型的范围和机器无关,每一种数据类型的取值范围固定


可以通过下面方式获取各个类型的字节数:

System.out.println("char:" + Character.SIZE);//char的长度是16
System.out.println("int:" + Integer.SIZE);//32
System.out.println("short:" + Short.SIZE);//16
System.out.println("long:" + Long.SIZE);//64
System.out.println("byte:" + Byte.SIZE);//8
System.out.println("float:" + Float.SIZE);//32
System.out.println("double:" + Double.SIZE);//64


转换关系:


在运算时,如果操作数类型不同会转换为同一类型,优先级为:double>float>long>int

对浮点数的舍入运算,得到的是最接近的整数

double y1=3.5,y2=3;
int x1=(int)Math.round(y1);//4
int x2=(int)Math.round(y2);//3
要强转成int,因为返回的是long

当强转使精度损失时,将高位字节截断,浮点数转整数去掉小数点后面的

int a=0b1_10000000;//不影响,128+256=384
byte b=(byte)0b1_10000000;//9位,多了一位,忽视第一位,补码,=-128
byte c=(byte)0b1_00000000;//忽视第一位,全0=0
(byte)300=44,只留300的后8位

整型

4种整型(都是有符号类型)
byte1字节-128 --- 127
short2字节-32768 --- 32767
int4字节正负20亿
long8字节 

byte a=(byte) 0b11111111;//输出-1
byte b=(byte) 0b10000000;//输出-128
byte c=(byte) 0b10000001;//输出-127
byte e= 0b1010000;//满8位时涉及最高位符号位,默认int,必须强转成byte、short,低于8位不需要转
short d=(short) 0b1000000000000000;//输出-32768

总之记住,补码表示的整数,全是1时取反+1,就是1.....1=-1啦

而100000则是最小的负数

长整型:后缀L(大小写都可以)

16进制:前缀0x(0X也可以)

8进制:前缀0

2进制:前缀0b


浮点数

2种浮点类型
float4字节(1符号位+8指数位+23尾数位)有效位数6~7位
double8字节(1符号位+11指数位+52尾数位)有效位数15位

看到一种说法:float放在内存中其实是当作double来处理的,它不会比double更节约内存资源,对应的double虚拟机会直接以double形式来进行处理,快速而且精度高,但是如果用float,不但不会节约内存资源,虚拟机为了校验float的精度,会花费更多的系统资源,例如cpu时钟,程序执行步骤等等。《Java核心技术》也认为float几乎很少用到,所以以后都用double吧

float后面要加F,没有后缀的浮点数都会默认为double

而double的指数范围:-1024~+1023

float的范围为-2^128 ~ +2^127(-3.40E+38 ~ +3.40E+38)这个正负2是因为,尾数部分最大为1.1111111.。。。?(第一位1默认确定)

double的范围为-2^1024 ~ +2^1023(-1.79E+308 ~ +1.79E+308)


float的指数范围:-128~+127(128还是127不太确定不过无所谓啦),8位都是数字位表示为0~255,然后减去一个偏差值127的方式得到-127~128总之范围基本一致。表示小数点可以左移127位(绝对值变小)到右移127位(绝对值变大)之间


尾数部分,规范规定,默认整数位是1,因此多了一位可以表示。23位却可以保存24位的尾数

博客中看到的例子:二进制的 1001.101(对应于十进制的 9.625)可以表达为 1.001101 × 2^3,所以实际保存在尾数域中的值为 00110100000000000000000,即去掉小数点左侧的 1,并 用 0 在右侧补齐。 (问题来了:第一位总是1,那浮点数的0咋表示)

所以可以表达的最大尾数为 2^24- 1 = 16,777,215 共8位,所以表示的十进制数字有效位小于等于8位


《Java核心技术》的意思可能是:2^23 = 8388608,一共七位,这意味着最多能有7位有效数字,但绝对能保证的为6位,也即float的精度为6~7位有效数字,可能都是没考虑默认位,都少了1位有效数字


补充一点IEEE 754标准的情况,从百度百科里来的:

IEEE 754定义了4种浮点数值,32位,64位,43位,79位以上

二进制浮点数是以符号数值表示法格式储存,将最高效位元指定为符号位元(sign bit);

“指数部份”,即次高效的e位元,为浮点数中经指数偏差(exponent bias)处理过后的指数;

“小数部份”,即剩下的f位元,为有效位数(significand)减掉有效位数本身的最高效位元。

指数偏差(表示法中的指数为实际指数减掉某个值)为 ,其中的e为存储指数的比特的长度。减掉一个值因为指数必须是有号数才能表达很大或很小的数值,但是有号数通常的表示法——补码(two's complement),将会使比较变得困难。为了解决这个问题,指数在存储之前需要做偏差修正,将它的值调整到一个无符号数的范围内以便进行比较。此外,指数采用这种方法表示的优点还在于使得浮点数的正规形式和非正规形式之间有了一个平滑的转变


Java的科学计数法,指数的基数是10,e或者E都行

System.out.println(2.0E-3);//输出2*10^(-3)=0.002


16进制的科学计数法,标识是P,且指数的基数是2

System.out.println(0x1P2);//1*2^2=4

char

char类型的长度为2字节(unicode编码就是2字节的)是16位无符号整数,可以将一个介于0x0000~0xffff之间的整数赋给char,超出则报错
\uxxxx是以unicode编码表示一个char字符,xxxx是16进制数

char b=\u0002;//错误,要加单引号
char b='\u002';//错误,unicode必须是4位数字,0也得加上去
char c='\u0002';//正确
String c="\u0041123";//字符串输出“A123”

A的char整数是65: ('A'和字符串"A"是不同的)
char a='\u0041';
char c=65;
//两个都输出‘A’

33~47:常用运算符、括号、$、%等
48~57:数字0~9
58~64:?、<、;等常用符号
65~90:A~Z
91~96:符号
97~122:a~z
(至少以上这些都是和ASCII码相同)

转义字符(escape character
一些字母前加"\"来表示常见的那些不能显示的ASCII字符,如\0,\t,\n等,就称为转义字符,因为后面的字符,都不是它本来的ASCII字符意思了
\b退格\u0008
\t制表\u0009
\n换行\u000a
\r回车\u000d
\"和\'引号\u0022、\u0027
\\反斜杠\u005c
正斜杠/不用转义

由于Unicode也不够用了,Java的char用UTF-16描述代码单元
建议不要在程序中使用char类型,除非确实需要对UTF-16代码单元进行操作

boolean类型

整型和boolean不能转换!
if(aa=0){}//错误,不能将整型转为boolean




  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值