一道程序题

  csdn看到如下一题.

 

 if(n>0) return 1;

  
else if(n == 0) return 0;

  
else return -1;

 

 

  不用任何条件控制语句实现该方法。

  首先整数的正与负非常好区分。符号位。但是0的符号位也为0。

  如果能够把大于0的数与小于0的数都变为1,0依然为0。然后根据符号,大于0的1依旧是1,小于0的根据符号为-1就好了

  我的思路:

  1、大于0的数最小为1

  2、小于0的数最大为-1

      3、 0 = 0

  由上3点并想到两个式子。

  a、x-1

  b、-1-x

  分析---a 式子:如果<0, =0的数则结果小于0符号位为1,>0的结果符号位为0

    ---b  式子:如果>0,=0的数则结果小于0符号位为1,<0的结果符号位为0

    从上看,0在两种情况都为1,而>0,<0的两种值为0或1。所只要将表达式的结果异或,那么0则为0,正负数都为1。

  表达式代码转换如下: uint exp = (((uint)(-1 - num)) >> 31) ^ (((uint)(num - 1)) >> 31);

 正数与负数想到的区别是符号位,正为0,负为1。 1 | 0 = 1, 1 | -1 = -1。

 -1等于1取反+1,同样0取反+1,高位溢出,同样为0。所以利用符号位0,1即可。0,-1分别与结果1,1做或运算了。

 将整数变为无符号的即可移动符号位(>>31),表达式如下: uint a = (~(((uint)num) >> 31)) + 1;

 

   函数代码如下(假设32位机):

代码
     int fun(int num)
{
uint a = (~(((uint)num) >> 31)) + 1;
uint exp = (((uint)(-1 - num)) >> 31) ^ (((uint)(num - 1)) >> 31);
int result = (int)(a | exp);
return result;
}

    这周面试的时候也遇到一道面试题目,乘以某个数也是移位处理。

    暂时只想到这样一个思路。自己记录下。

   同事给出的解法2:

  return Convert.ToInt32(x>0) - Convert.ToInt32(x<0);

   同学给出的解法3:

     return Convert.ToInt32(x != 0) | ((~(((uint)num) >> 31)) + 1);

    我没想出的原因: 在将bool转换为Int32的时候出问题.我直接(int)(x>0)的时候编译没通过,误以为C#里面不能转换........;

    为什么不能像C语言一样可以直接转换,我觉得也是个值得思考的问题......

   还有,有同学说我的解法Int32.MinValue会溢出,出错,其实没关系的,答案依然正确.

    补充完毕

posted @ 2010-05-28 21:34  HQL  阅读(300)  评论(0编辑  收藏  举报