关于Java中数值计算的一些误区
2015-09-26 23:09
375 查看
今天在跟着视频做坦克大战的时候,在写一个血条的类,里面的draw方法涉及到一个计算问题,即:当前血条的长度是由当前血量/总血量得到一个比例再去乘以总血量的值,从而得到一个血条的长度值,然后将其绘制出来。具体代码如下:
问题出在我被我注释的哪一行上面,反应在游戏中就是血块开始是满的,被炮弹一打,就直接没有了,我百思不得其解,视频上的写法是width * life / 100,这两种写法的结果应该是一样的呀,怎么会这样呢,后来通过debugger发现,炮弹打到坦克时,(life / 100) * 100的值直接等于0了,看来是数据在转换的时候出来问题,后来经过回忆Java中默认的数据类型整数是int,而小数是dobule,难道不光运算结果会强制转换类型,连在运算过程中也会强制转换类型?为了验证我的想法,就有了下面的写法:
这次我再运行,OK,一切正常。 好了,现在我来分析下过程,本来采用(life / 100) * WIDTH这种写法在数学公式上是没有问题,但Java中不同的数据类型,life是int型在计算的时候,life/100的结果如果是小数(默认为double类型)就会被会强制转换成int型(结果为0),从而导致life/100只有两种计算结果,即0或1,所以出现上面所说的那种情况。
总结:
看来我之前忽视了, 在Java的运算中不光计算结果会产生强制类型转换,运算过程的中间值中也会产生强制类型转换,所以如果想要保证结果的正确,请务必保证运算的过程中所有的值(包括运算值[b]、中间值、[/b]结果)的数据类型都相同。
public void draw(Graphics g) { Color c = g.getColor(); g.setColor(Color.RED); g.drawRect(x, y - 10, WIDTH, 10);//空心血条 //我的写法是如下的: //int w = (life / 100) * WIDTH; int w = WIDTH * life / 100; g.fillRect(x, y - 10, w, 10);//绘制实心血条,即当前血量 g.setColor(c); } }
问题出在我被我注释的哪一行上面,反应在游戏中就是血块开始是满的,被炮弹一打,就直接没有了,我百思不得其解,视频上的写法是width * life / 100,这两种写法的结果应该是一样的呀,怎么会这样呢,后来通过debugger发现,炮弹打到坦克时,(life / 100) * 100的值直接等于0了,看来是数据在转换的时候出来问题,后来经过回忆Java中默认的数据类型整数是int,而小数是dobule,难道不光运算结果会强制转换类型,连在运算过程中也会强制转换类型?为了验证我的想法,就有了下面的写法:
double l = life; double d = (life / 100.0) * WIDTH; int w = (int)d;
这次我再运行,OK,一切正常。 好了,现在我来分析下过程,本来采用(life / 100) * WIDTH这种写法在数学公式上是没有问题,但Java中不同的数据类型,life是int型在计算的时候,life/100的结果如果是小数(默认为double类型)就会被会强制转换成int型(结果为0),从而导致life/100只有两种计算结果,即0或1,所以出现上面所说的那种情况。
总结:
看来我之前忽视了, 在Java的运算中不光计算结果会产生强制类型转换,运算过程的中间值中也会产生强制类型转换,所以如果想要保证结果的正确,请务必保证运算的过程中所有的值(包括运算值[b]、中间值、[/b]结果)的数据类型都相同。
相关文章推荐
- 远程下载pdf文件 java代码
- Eclipse 启动报错 'Failed to load the JNI share ... jvm.dll' 解决方法
- java当中float以及double数据类型的掌握
- Struts2架构流程
- 最长和为零的子数组与最大子矩阵
- java5:运算
- 谈spring的bean的生命周期相关的类
- Java Base64编码和解码
- Java:详解传值和传引用
- 用JAVA做一个用户登入系统
- Java:Integer的值问题
- Java学习笔记【异常、断言】
- Java:i++问题(详细分析)
- java正则表达式积累
- Java输出一个对象
- Java 常用正则表达式
- Spring(六):Bean 的作用域
- 关于java中除0的问题
- 搭建JavaWeb项目时出现的问题
- 浅识异常