免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 949 | 回复: 0
打印 上一主题 下一主题

java解惑学习笔记1 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2007-02-01 19:35 |只看该作者 |倒序浏览

                java解惑学习笔记:1.【奇数性】书中谈到取余操作的符号时用到了:(a / b) * b + (a % b) == a,来说明a % b的符号和a是相同的。例如:a = -5,b=2,a/b = -2, (a / b) * b = -4,所以a % b必然是-1。修正放案:       ★ 1.public static boolean isOdd(int i) {           return i % 2 != 0; }      ★★2. 对i求绝对值后进行取模运算。      ★★3.public static boolean isOdd(int i) {           return (i & 1) != 0;        }     2.【找零时刻】 public class Change{           public static void main(String args[]){     System.out.println(2.00 - 1.10);           }        }真没想到会打印出那样的一个结果:0.8999999999999999.晕!真长啊!Double.toString()中描述的规则是:There must be at least one digit to represent the fractional part, and beyond that as many, but only as many, more digits as are needed to uniquely distinguish the argument value from adjacent values of type float. That is, suppose that x is the exact mathematical value represented by the decimal representation produced by this method for a finite nonzero argument f. Then f must be the float value nearest to x; or, if two float values are equally close to x, then f must be one of them and the least significant bit of the significand of f must be 0.(大意是:至少要用一个数来表达小数部分,而且尽可能多,但是只需能把这个值和它邻接的float型数据区分开就足够了。也就是说,假如x是对于有限非零实参f用这种方式产生的十进制的精确数学表述,f必定是最接近x的float型数据,或者如果两个float值是与x同样的接近(数轴上),f必定是它们中的一个并且f的最少有效位必须是0)瞎扯了一大堆还是没搞明白是什么意思,试试这个double d =2.0;double f = 1.10;double result = d - f;System.out.println(result);打印是仍旧是:0.8999999999999999。原来如此,并不是toString搞得怪,是原本就算错了。并不是所有的小数都可以用二进制浮点数来精确表示的(书上),但是什么样的浮点数数据是java能过正确表示的????SOLUTION:●1.拙劣的解决方案 - 障眼法System.out.printf("%.2f%n",2.00 - 1.10);★★★2.使用某种整数类型,例如int和long(较优)System.out.println((200 - 110) + "cents");★★3.使用执行精确小数运算的BigDecimalimport java.math.BigDecimal;public class Change1{ public static void main(String args[]){  System.out.println(new BigDecimal("2.00").  subtract(new BigDecimal("1.10"))); }}3.【长整除】public class LongDivision{ public static void main(String args[]){  final long MICROS_PER_DAY = 24 * 60 * 60 * 1000 * 1000;  final long MILLIS_PER_DAY = 24 * 60 * 60 * 1000;  System.out.println(MICROS_PER_DAY/MILLIS_PER_DAY); }}结果是什么? 还用想肯定是1000。OH my god !活见鬼居然是5.java不具有目标确定类型的特性所以24 * 60 * 60 * 1000 * 1000计算的结果先放在一个中间变量中,最后通过windening  conversion提升为long型 ,24 * 60 * 60 * 1000 * 1000 =86400000000 而int型数据表示范围是-2147483648~2147483647很明显是溢出了。关键问题是:在编译中使用的中间变量是由计算的数据决定而不是结果的类型(个人看法)。SOLUTION:public class LongDivision{ public static void main(String args[ ]){  final long MICROS_PER_DAY = 24L * 60 * 60 * 1000 * 1000;  final long MILLIS_PER_DAY = 24L * 60 * 60 * 1000;  System.out.println(MICROS_PER_DAY/MILLIS_PER_DAY); }正如书上描述的溢出是一个沉默的杀手,我们在尽力避免它的发生,没想到还会遇到这样的事。即使用来保存结果的变量已显得足够大,也并不意味着要产生结果的计算具有正确的类型。当你拿不准时,就使用long运算来执行整个计算。(java的这个缺陷也太菜了吧!)
 
 
               
               
               

本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u/28187/showart_241625.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP