一道程序题
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会溢出,出错,其实没关系的,答案依然正确.
补充完毕