[java puzzles]puzzle:Oddity

The following method purports to determine whether its sole argument is an odd number.Does the method work?

 

public static boolean isOdd(int i){

          return i % 2 ==1;

}

 

Solution:

 

An Odd number can be defined as an integer that is divisible by 2 with a remainder of 1.The expression i % 2

 

computes the remainder when i is divided by 2, soit would semm that this program ought to work.Unfortunately, it

 

doesn't;it returns the wrong answer one quarter of the time;

 

        Why one quarter? Because half of all int values are negative, and the isOdd method fails for all negative odd

 

values.It returns false when invoked on any negative value, whether even or odd.

 

        This is a consequence of the definition of Java's remainder operator (%).It is defined to satisfy the following

 

identity for all int values a and all nonzero int values b:

 

         (a / b) * b + (a % b) == a

 

In other words, if you divide a by b, multiply the result by b, and add the remainder, you rare back where you started

 

[JLS 15.17.3].This identity makes perfect sense, but in combination with Java's truncating integer division operator

 

[JLS 15.17.2],it implies that when the remainder operation returns a nonzero result, it has the same sign as its left

 

operand.

 

           The is Odd method and the definition of the term odd on which it was based both assume that all remainders

 

are positive. Although this assumption make sense for some kinds of division [Boxing],Java's remainder operation is

 

perfect matched to its integer division operation, which discards the fractional part of its result.

 

        When i is a negative odd number, i % 2 is equal to -1 rather than 1,so the isOdd method incorrectly returns

 

false.To prevent this sort of surprise,test that your method behave properly when passed negative, zero, and

 

positive values for each numerical parameters.

 

        The problem is easy to fix. Simply compare i% 2 to 0 rather than to 1,and reverse the sense of the comparison:

 

        public static boolean isOdd(inti){

                    return i % 2 != 0;

       }

 

        If you are using the isOdd method in a performance-critical setting, you would be better off using the bitwise

 

AND operator (&) in place of the remainder operator:

 

        public static boolean isOdd(int i) {

                    return (i & 1) != 0;

       }

 

        The second version may run much faster than the first, depending on what platform and virtual machine you are

 

using, and is unlikely to run slower.As a general role, the divide and remainder operations are slow compared to

 

other arithmetic and logical operations.It's a bad idea to optimize prematurely, but in this case, the faster version is

 

as clear as the original, so there is no reason to prefer the original.

 

        In summary, think about the signs of the operands and of the result whenever you use the remainder

 

operator.The behavior of this operator is obvious when its operands are nonnegative,but it isn't so obvious when

 

one or both operands are negative.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值