基础-基本数据类型问题

基本数据类型(8种)

  1.   整型:long(8字节)、int(4字节、默认)、shot(2字节)、byte(1字节8位二进制表示)---转换成二进制直接存储
  2.   浮点型:double(8字节、默认)、float(4字节)---科学计数法存储
  3.   逻辑型:bollean(1字节)---true、false
  4.   字符型:char(2字节)


数据类型转换:

byte--->short--->int--->long--->float--->double
char--->int

对数据进行操作时注意溢出和舍入误差问题。

byte b1=1;
byte b2=2;
byte b=b1+b2;//编译错误。byte、shot型的运算,先转换成int,故结果要强制转换
byte b=(byte)(b1+b2);//编译正确  
byte b=(byte)(b1+b2+126);//结果错误。byte为8位二进制,结果超出范围,溢出

溢出:

2的32次方=4294967296(无符号),带符号再除以2,负数比正数多一个,-2147483648~+2147483647。

当最小值再减小1,就会变成最大值;最大值再增加1,则会变成最小值;这种现象称为溢出。

舍入误差:

现象:

double j=3.0;
double k=2.9;
System.out.println("j-k =  "+(j-k)); //结果为0.10000000000000009---舍入误差类似于十进制的1/3表示
double j1=4.0;
double k1=2.9;
System.out.println("j1-k1 =  "+(j1-k1)); //结果为1.1
double j2=6.0;
double k2=4.9;
System.out.println("j2-k2 =  "+(j2-k2)); //结果为1.0999999999999996---舍入误差

原因:(摘自http://blog.csdn.net/aya19880214/article/details/45891581。在这里谢谢博主分享)

首先得从计算机本身去讨论这个问题。我们知道,计算机并不能识别除了二进制数据以外的任何数据。无论我们使用何种编程语言,在何种编译环境下工作,都要先 把源程序翻译成二进制的机器码后才能被计算机识别
以上面提到的情况为例,我们源程序里的2.4是十进制的,计算机不能直接识别,要先编译成二进制。但问 题来了,0.1的二进制表示并非是精确的0.1,反而最为接近的二进制表示是0.10000000000000009。原因在于浮点数由两部分组成:指数和尾数,这点如果知道怎样进行浮点数的二进制与十进制转换,应该是不难理解的。如果在这个转换的过程中,浮点数参与了计算,那么转换的过程就会变得不可预 知,并且变得不可逆。我们有理由相信,就是在这个过程中,发生了精度的丢失。而至于为什么有些浮点计算会得到准确的结果,应该也是碰巧那个计算的二进制与 十进制之间能够准确转换。 当输出单个浮点型数据的时候,可以正确输出,如

double d = 0.1;
System.out.println(d);

输出的是0.1,而不是0.10000000000000009。也就是说,不进行浮点计算的时候,在十进制里浮点数能正确显示。这更印证了我以上的想法,即如果浮点数参与了计算,那么浮点数二进制与十进制间的转换过程就会变得不可预知,并且变得不可逆。

事实上,浮点数并不适合用于精确计算,而适合进行科学计算。这里有一个小知识:既然float和double型用来表示带有小数点的数,那为什么我们不称 它们为“小数”或者“实数”,要叫浮点数呢?因为这些数都以科学计数法的形式存储。当一个数如50.534,转换成科学计数法的形式为5.053e1,它 的小数点移动到了一个新的位置(即浮动了)。可见,浮点数本来就是用于科学计算的,用来进行精确计算实在太不合适了。

解决方法:

使用java.math.BigDecimal类---专门精确计算浮点数的类。缺点是运行速度慢,需要调用运算方法来计算。

BigDecimal.setScale()方法用于格式化小数点
setScale(1)表示保留一位小数,默认用四舍五入方式 
setScale(1,BigDecimal.ROUND_DOWN)直接删除多余的小数位,如2.35会变成2.3 
setScale(1,BigDecimal.ROUND_UP)进位处理,2.35变成2.4 
setScale(1,BigDecimal.ROUND_HALF_UP)四舍五入,2.35变成2.4
setScaler(1,BigDecimal.ROUND_HALF_DOWN)四舍五入,2.35变成2.3,如果是5则向下舍

BigDecimal其中一个构造函数以双精度浮点数作为输入,另一个以整数和换算因子作为输入,还有一个以小数的String表示作为输入。

注意:要小心使用BigDecimal(double)构造函数,因为如果不了解它,会在计算过程中产生舍入误差。请使用基于整数或String的构造函数。

如果使用 BigDecimal(double) 构造函数不恰当,在传递给 JDBC setBigDecimal() 方法时,会造成似乎很奇怪的 JDBC 驱动程序中的异常。例如,考虑以下 JDBC 代码,该代码希望将数字0.01存储到小数字段:

PreparedStatement ps = connection.prepareStatement("INSERT INTO Foo SET name=?, value=?");
ps.setString(1, "penny");
ps.setBigDecimal(2, new BigDecimal(0.01));
ps.executeUpdate();
在执行这段似乎无害的代码时会抛出一些令人迷惑不解的异常(这取决于具体的 JDBC 驱动程序),因为0.01的双精度近似值会导致大的换算值,这可能会使 JDBC 驱动程序或数据库感到迷惑。JDBC驱动程序会产生异常,但可能不会说明代码实际上错在哪里,除非意识到二进制浮点数的局限性。相反,使用 BigDecimal("0.01")或BigDecimal(1,2)构造BigDecimal来避免这类问题,因为这两种方法都可以精确地表示小数。
float和double只能用来做科学计算或者是工程计算,在商业计算中我们要用java.math.BigDecimal。使用BigDecimal并且一定要用String来够造。

字符定义:

char c1='男';
//char c5='男性'; //错误
char c2='m';
char c3='6';
char c4=' ';
char c6=65; //表面上为字符型,实质上是整型
System.out.println(c6); //输出为字符型
System.out.println((int)c6); //输出时将字符型强制转换成了整型
System.out.println('2'+'2');
System.out.println(2+'2');
System.out.println(2+2);
char c7='\'';
System.out.println(c7);
char c8='\n';
System.out.println(c8); //println一次换行,\n一次换行
System.out.println('2'+'2');
每个char型变量占16bit(位),即就是两个字节。
在Java中字符的编码不是ASCII码,而是采用的Unicode编码。Unicode编码字符是用16位无符号整数表示的。有2的16次方(0-65535)个可能值。
字符有三种定义方式:
  • 直接使用一对单引号包含的单个字符:char c1 = 'E';
  • 通过Unicode编码值(\u0000-\uFFFF)直接表示:char c2 = '\u004E'; //表示大写字母E
  • 使用整数(0-65535)直接赋值:char c3 = 65; //大写字母A
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值