`
ZangXT
  • 浏览: 118067 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

读Java Puzzlers笔记: 表达式问题

阅读更多

    一.奇数性
判断一个数是否为奇数,方法:

  1. publicstaticbooleanisOdd(inti){
  2. return(i%2)!=0;
  3. }

或者:

  1. publicstaticbooleanisOdd(inti){
  2. return(i&1)!=0;
  3. }

不要使用i%2==1来判断,因为它无法判断负奇数的情况.

二.浮点数
浮点数计算一直是计算机中一个比较困难的问题,William (Velvel) Morton Kahan就因为他在数值分析领域基础性的贡献而获得了图灵奖,他也是IEEE754标准的主要设计者。关于这个标准,计算机组成原理或者系统结构的书上都有介绍。
  浮点数不是精确表示的,所以涉及到精确计算的情况(比如货币),不要使用float,double,而要使用BigDecimal类(使用String构造)。
例子:

  1. System.out.println(2.00-1.10);

可以使用下面代码代替:

import java.math.BigDecimal;

  1. System.out.println(newBigDecimal("2.00").subtract(newBigDecimal("1.10")));

三.长整除
题目:

  1. finallongMICROS_PER_DAY=24*60*60*1000*1000;
  2. finallongMILLIS_PER_DAY=24*60*60*1000;
  3. System.out.println(MICROS_PER_DAY/MILLIS_PER_DAY);

结果: 5

24*60*60*1000*1000,24,60这些字面常量都是int类型的,它们计算的结果也是int类型,但是int类型无法保存这么大的结果,因此计算过程中会产生溢出,从而带来不正确的结果.教训:当操作很大的数字时,千万要提防溢出.
 把程序修改一下:  

  1.   finallongMICROS_PER_DAY=24L*60*60*1000*1000;
  2. finallongMILLIS_PER_DAY=24L*60*60*1000;
  3. System.out.println(MICROS_PER_DAY/MILLIS_PER_DAY);

   还要注意使用Long类型的常量时用大写字母L表示,因为小写的l跟数字1看起来很像,给看代码和理解代码带来了困难.

四.多重转换
  题目:  

  1. System.out.println((int)(char)(byte)-1);

输出是:65535

如果最初的数值类型是有符号的,那么就执行符号扩展;如果它是char,那么不管它将要被转换成什么类型,都执行零扩展.
如果对结果有特殊要求,使用掩码和位运算以达到自己的目标.

五.互换内容
题目:

  1. intx=1984;
  2. inty=2001;
  3. x^=y^=x^=y;
  4. System.out.println("x="+x+";y="+y);

结果是: x=0;y=1984
Java语言规范中描述了:操作符的操作数都是从左向右求值的.为了求表达式x^=expr的值,在计算expr之前提取x的值,并且将这两个值的异或结果赋给变量x.在上面的题目中,变量x 的值被提取了两次,每次在表达式中出现时都提取一次,但是两次提取都发生在所有的赋值操作之前.
下面的代码详细地描述了将互换管用法分解之后的行为,并且解释了为什么产生的是看到的输出:
  

  1.   inttmp1=x;
  2. inttmp2=y;
  3. inttmp3=x^y;
  4. x=tmp3;
  5. y=tmp2^tmp3;
  6. x=tmp1^y;

  这个具体的转换过程考虑单独写文再分析一下.   
  教训:在单个的表达式中不要对相同的变量赋值两次.要避免所谓聪明的编程技巧.
   

六: ?:表达式
  题目:  

  1.    charx='X';
  2. inti=0;
  3. System.out.println(true?x:0);
  4. System.out.println(false?i:x);

输出:
X
88

混合类型的计算会引起混乱,而这一点在条件表达式中比其他任何地方都更明显.
  确定条件表达式结果类型的规则核心是以下三点:
(1)如果第二个和第三个操作数具有相同的类型,那么它就是条件表达式的类型.换句话说,可以通过绕过混合类型的计算来避免大麻烦.
(2)如果一个操作数的类型是T,T表示byte,short或char,而另一个操作数是一个int类型的常量表达式(字面常量或者final常量),它的值可以用类型T表示,那么条件表达式的类型就是T.
(3)否则,将对操作数类型进行二进制数字提升,而条件表达式的类型就是第二个和第三个操作数被提升之后的类型.
理解了这三点,本题的例子也就解决了.
条件表达式的类型将决定调用哪一个重载的print方法.
总之,通常最好是在条件表达式中使用类型相同的第二和第三操作数.

七.复合赋值运算符Compound Assignment Operators
下面这个例子是最常见的了,论坛里也是隔三差五就有人拿出来问:   

  1.   shorts=0;
  2. s+=1;//ok
  3. s=s+1;//error

   先看java语言规范中的描述:
   All compound assignment operators require both operands to be of primitive type, except for +=, which allows the right-hand operand to be of any type if the left-hand operand is of type String.

A compound assignment expression of the form E1 op= E2 is equivalent to E1 = (T)((E1) op (E2)), where T is the type of E1, except that E1 is evaluated only once. Note that the implied cast to type T may be either an identity conversion or a narrowing primitive conversion. For example, the following code is correct:


short x = 3;
x += 4.6;

and results in x having the value 7 because it is equivalent to:


short x = 3;
x = (short)(x + 4.6);

  复合赋值表达式自动地将所执行计算的结果转型为其左侧变量的类型.
  java中,对byte,short和char类型的运算都是通过将它们提升为int类型进行的,所以计算的结果是int 类型,如果要
把结果赋值给一个更窄的类型,需要自己加上强制类型转换.更深层次的原因可以去看jvm中提供的相关运算指令.
  从JLS上的介绍同时要注意到另一个问题,String类型重载了+=操作符,并支持任何类型的右操作数.
分享到:
评论
1 楼 langyu 2009-11-11  
你好

刚看到第一条,判断奇偶性用(i&2)!=0,这句是有问题的,应该用(i&1)==1来判断的。
因为对于奇数,它的后两位要么是01要么是11,特点是最后一位肯定是1,那么就要和1来按位操作。

但判断奇偶性还是不要这么做的好点,(i%2)!=0多清晰啊,就是大量使用的话速度慢了点,但还是没有多少问题的

相关推荐

    Java™ Puzzlers: Traps, Pitfalls, and Corner Cases.chm

    Java™ Puzzlers: Traps, Pitfalls, and Corner Cases.chm,英文版本,chm 格式,大小 1 Mb,作者:Joshua Bloch、Neal Gafter。 内容预览: Chapter 1. Introduction Chapter 2. Expressive Puzzlers Puzzle 1: ...

    Java Puzzlers 中文版(Java解惑)

    Java Puzzlers 中文版(Java解惑) Java 谜题 1——表达式谜题 谜题 1:奇数性 下面的方法意图确定它那唯一的参数是否是一个奇数。这个方法能够正确运转 吗? public static boolean isOdd(int i){ return i % 2 == 1...

    JAVA PUZZLERS(JAVA 解惑)中英文

    《JAVA PUZZLERS》是一本深受欢迎的Java编程书籍,旨在揭示编程语言中的微妙陷阱和易犯错误,帮助开发者提升编程技能和理解。这本书以其独特的“谜题”形式,通过一系列精心设计的问题,引导读者探索Java语言的深奥...

    Java Puzzlers完整中文版

    谜题 40:不情愿的构造器 尽管在一个方法声明中看到一个 throws 子句是很常见的,但是在构造器的声明 中看到一个 throws 子句就很少见了。下面的程序就有这样的一个声明。那么, 它将打印出什么呢?...

    java puzzlers code

    此外,Java Puzzlers 还会探讨一些多线程问题,如线程安全、synchronized关键字的使用以及并发工具类的正确操作。这些谜题揭示了多线程编程中的常见误解和陷阱,帮助你构建出更健壮的并发应用程序。 总的来说,...

    java Puzzlers 中文版带完整目录

    本書包含了Java程式語言和核心函式庫中的各種謎題,任何具備使用Java經驗的讀者都可以看得懂,但是書裡有不少謎題的難度頗高,即便是對經驗豐富的Java程式設計師而言,都是一項挑戰,所以如果你解不出來,別覺得難過...

    Java Puzzlers(韩语版)

    Java Puzzlers(韩语版) 讲述了java中容易混淆的问题。 值得一看!

    Java puzzlers(java 解惑)附源码

    《Java Puzzlers》是一本深受Java开发者喜爱的书籍,由Joshua Bloch和Neal Gafter合著。这本书专门探讨了Java编程语言中容易让人迷惑的陷阱和常见误解,通过一系列精心设计的“puzzlers”(谜题)来揭示这些陷阱,并...

    java puzzlers 中文版.doc

    java puzzlers 中文版

    <好书>java解惑(java puzzlers),过来挑战吧

    1. 类型转换:Java是一种静态类型语言,但类型转换时可能出现问题,如自动装箱拆箱可能导致的意外行为,或者是不恰当的强制类型转换导致的ClassCastException。 2. 对象引用:Java中的对象引用有时会让人迷惑,例如...

    Java+Puzzlers(中英文并且带源码)

    5. **访问修饰符**:Java的public、private、protected和默认访问修饰符的使用有明确的规定,Puzzlers可能涉及它们在不同包中的可见性问题。 6. **异常处理**:Java的异常处理机制是一个重要的话题,Puzzlers可能...

    Java学习推荐书(包含各类java入门)

    2. 《Java Puzzlers》:通过谜题介绍一些你可能没有注意到的边角料,这本书可以作为趣味读物,也可以帮助读者深入理解 Java 的特性。 3. 《深入 Java 虚拟机》:这本书提供了 Java 虚拟机的详细介绍,帮助读者深入...

    java-puzzlers-sampler_java_Joshua_

    《Java Puzzlers Sampler》是由Java领域的权威专家Joshua Bloch和Neal Gafter共同编著的一本书,书中收录了一系列令人困惑、出乎意料的Java编程问题,旨在帮助开发者更好地理解和避免这些潜在的陷阱。书中的...

    java-puzzlers源代码

    1. **类型转换和自动装箱拆箱**:Java中的基本类型与对应的包装类之间可以进行自动转换,但这种转换可能隐藏着一些潜在的问题,如精度丢失、隐式转型等。 2. **变量作用域**:Java中变量的作用域是严格控制的,包括...

    java谜题中文版

    综上所述,`java_puzzlers`中文版中的这两个谜题,揭示了Java编程中容易忽视的细节,包括取余运算的符号敏感性和浮点数计算的不精确性。通过深入理解这些问题及其解决方案,开发者可以编写更加健壮和准确的代码。

    Java解惑 清晰版带书签

    根据提供的文件信息,“Java解惑 清晰版带书签”这一标题暗示这是一本深入探讨Java编程语言中常见问题及解决方案的专业书籍。该书由《Effective Java》的作者所著,因此我们可以推断出这本书将包含许多实用的Java...

    java爱好者必备JAVA解惑(pdf格式)

    《JAVA解惑》是一本专为Java爱好者设计的书籍,旨在帮助读者解决在学习和使用Java过程中遇到的各种问题。这本书以PDF格式提供,方便电子阅读和保存。在深入探讨Java编程语言的过程中,它覆盖了从基础概念到高级特性...

    java puzzlers

    JAVA解惑 中文和英文 Like many books, this one had a long gestation period. We've collected Java puzzles for as long as we've worked with the platform: since mid-1996, in case you're curious. In early...

    JavaSIG-Puzzlers.pdf

    《JavaSIG-Puzzlers.pdf》是一本由Joshua Bloch与Neal Gafter共同编写的书籍,该书主要探讨了Java编程语言中的一些非常规问题。这些问题是开发者在日常工作中可能会遇到但又容易忽视的陷阱或难点。书中通过一系列的...

Global site tag (gtag.js) - Google Analytics