码迷,mamicode.com
首页 > 编程语言 > 详细

温故而知新---Java(一)

时间:2017-08-05 14:57:09      阅读:295      评论:0      收藏:0      [点我收藏+]

标签:误差   数据类型   字符   文章   自增   16px   输出   技术分享   针对   

学习不仅要学习新的东西,而且还要时不时的回过头捡漏...

本文参考老马说编程系列等文,在此推荐大家关注老马说编程系列文章

正文

基础知识

数据类型主要是为了对数据进行分类,方便理解和操作,在Java中,有如下基本数据类型:

  • 整数类型:有四种整型 byte/short/int/long,内存空间分别占用1/2/4/8个字节
  • 小数类型:有两种类型 float/double,,内存空间分别是占用4/8个字节
  • 字符类型:char,表示单个字符,内存空间是占用2个字节
  • 真假类型:boolean,表示真假

对象是一种基本数据类型、数组和其他对象组合而成的一个比较复杂的数据类型

内存可以直接理解成一个很长的数组,CPU可以直接定位到内存中的任何一个位置

变量的起源是由于将数据类型置于内存后,为了方便地找到和操作这个数据,给这个位置起的一个名字;所以叫变量,是因为它仅仅表示的是内存中的位置,这个位置存放的值是可以变化的

内存表示

一个基本类型变量,内存中只会有一块对应的内存空间。但数组有两块,一块用于存储数组内容本身,另一块用于存储内容的位置。

技术分享

上图在进一步解释,就是我们经常说的,基本数据类型保存的是值本身,而引用类型保存的是值所在的位置

 运算规则

运算时要注意结果的范围,使用恰当的数据类型。两个正数都可以用int表示,但相乘的结果可能就会超,超出后结果会令人困惑

int a = 2147483647*2; //2147483647是int能表示的最大值

a的结果是-2。为什么是-2我们暂不解释,要避免这种情况,我们的结果类型应使用long,但只改为long也是不够的,因为运算还是默认按照int类型进行,需要将至少一个数据表示为long形式,即在后面加L或l,下面这样才会出现期望的结果:

long a = 2147483647*2L;

另外,需要注意的是,整数相除不是四舍五入,而是直接舍去小数位:

double d = 10/4;

结果是2而不是2.5,如果要按小数进行运算,需要将至少一个数表示为小数形式,或者使用强制类型转化,即在数字前面加(double),表示将数字看做double类型,如下所示任意一种形式都可以:

double d = 10/4.0; 

double d = 10/(double)4;

 

在进行小数运算的时候,经常会出现一些很奇怪的值,比如执行

技术分享

这是由于计算机底层对于浮点数(小数)表示并不精确导致的,归根到底都是由于2进制的原因

自增/自减是对自己做加一和减一操作,但每个都有两种形式,一种是放在变量后,例如a++, a--,另一种是放在变量前,例如++a, --a

1 int a = 0;
2 System.out.println(a++);//0
3 int b = 0;
4 System.out.println(++b);//1
5 int c = 0;
6 System.out.println(c--);//0
7 int d = 0;
8 System.out.println(--d);//-1

逻辑运算符具体有如下几种

  • 与(&):两个都为true才是true,只要有一个是false就是false
  • 或(|):只要有一个为true就是true,都是false才是false
  • 非(!):针对一个变量,true会变成false, false会变成true
  • 异或(^):两个相同为false, 两个不相同为true
  • 短路与(&&): 和&类似,不同的是A&B,如果A是false还需在判断B是false,而A&&B,如果A是false,那么直接就是false
  • 短路或 (||):与|类似,不同的是A|B,如果A是true还需在判断B是true,而A||B,如果A是true,那么直接就是true

补充

补码

二进制使用最高位表示符号位,用1表示负数,用0表示正数。但负数表示不是简单的将最高位变为1,比如:

  • byte a = -1,如果只是将最高位变为1,二进制应该是10000001,但实际上,它应该是11111111。
  • byte a=-127,如果只是将最高位变为1,二进制应该是11111111,但实际上,它却应该是10000001。

这种表示法称为补码表示法,而符合我们直觉的表示称为原码表示法,补码表示就是在原码表示的基础上取反然后加1。取反就是将0变为1,1变为0。为什么负数要使用补码的形式呢?这是因为补码在计算加减的时候能保证是正确的!

位移操作

  • 左移:操作符为<<,向左移动,右边的低位补0,高位的就舍弃掉了,将二进制看做整数,左移1位就相当于乘以2。

  • 无符号右移:操作符为>>>,向右移动,右边的舍弃掉,左边补0。

  • 有符号右移:操作符为>>,向右移动,右边的舍弃掉,左边补什么取决于原来最高位是什么,原来是1就补1,原来是0就补0,将二进制看做整数,右移1位相当于除以2。

 有的小数计算为什么是正确的

System.out.println(0.1f+0.1f);  //0.2

System.out.println(0.1f*0.1f);  //0.010000001

 

 按照上面所说的,第一行应该不等于0.2才是正确的,但是为什么等于0.2呢?其实,这只是Java语言给我们造成的假象,计算结果其实也是不精确的,但是由于结果和0.2足够接近,在输出的时候,Java选择了输出0.2这个看上去非常精简的数字,而不是一个中间有很多0的小数。在误差足够小的时候,结果看上去是精确的,但不精确其实才是常态。如果真的需要比较高的精度,一种方法是将小数转化为整数进行运算,运算结束后再转化为小数,另外的方法一般是使用十进制的数据类型,这个没有统一的规范,在Java中是BigDecimal

 

温故而知新---Java(一)

标签:误差   数据类型   字符   文章   自增   16px   输出   技术分享   针对   

原文地址:http://www.cnblogs.com/sachen/p/7290038.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!