采访qns ...在没有任何条件或比较运算符的情况下执行以下操作

时间:2009-05-18 07:14:06

标签: algorithm math

在没有任何条件或比较运算符的情况下执行以下操作。

if (Number <= 0)
{
    Print '0';
}
else
{
    print Number;
}

感谢..

6 个答案:

答案 0 :(得分:13)

我最初的简单解决方案:

1. print( (abs(Number)+Number) / 2 )

该解决方案在大多数情况下都有效,除非Number非常大(超过最大值的一半,例如Number&gt; = MAX_INT / 2),在这种情况下,添加可能会导致溢出。

以下解决方案解决了溢出问题:

2. print( (abs(Number)/2) + (Number/2) )

但是,可能存在Number是且必须保持整数的情况,并且除法运算符(/)是整数除法,因此7/2 = 3。在这种情况下,解决方案2将无法工作,因为如果Number = 7,它将打印6(对于这种情况,解决方案1将正常工作)。

因此,如果我们需要处理大数和整数运算,下面的怪物就会出现挽救,在奇数为1的情况下,在除法中可能会丢失1的补偿:

3. print( 
    ( (abs(Number)/2)+(Number/2) ) +
    ((
        (Number-(2*(Number/2))) + 
        (abs(Number)-(2*(abs(Number)/2)))
    ) / 2)
    )        

答案 1 :(得分:9)

print max(0, number)

答案 2 :(得分:9)

假设该数字由8位二进制补码整数表示。

包括0的正数都将MSB设置为0。

负数都将MSB设置为1。

因此我们采用MSB的补码,将其扩展为完整的8位,并将其与原始数字进行按位AND,例如。

肯定:

00110101 - &gt; MSB为0

11111111 - &gt;补充MSB扩展

00110101 - &gt;按位AND以上

阴性:

10110101 - &gt; MSB是1

00000000 - &gt;补充MSB扩展

00000000 - &gt;按位AND以上

不需要进行比较 - 我有点假设按位AND并不是严格意义上的比较。

另外,对于缺少代码感到抱歉,但是你明白了。

答案 3 :(得分:0)

我还没有看到对整个域名有效的解决方案。

另一个解决方案是调用一个函数,如果输入值为0或低于0,则引发异常。然后捕获异常并打印0。

或者你可以使用一个函数Sign,如果输入是&lt; 0则返回-1,如果是0则返回0,否则返回1.

print ((sign(x)+1) * sign(x) / 2) * x.

符号可以是-1,0或1,因此((sign(x)+1)* sign(x)/ 2)可以具有以下值:

-1 -> ((-1+1)*-1)/2 = 0
 0 -> ((0+1)*0)/2 = 0
 1 -> ((1+1) * 1)/2  = 1

另一种方法是创建一个查找表,将所有非负数映射到自己,其余的映射到0。

但是,在我看来,原来的功能更加清晰。那么为什么要违反KISS原则呢。

答案 4 :(得分:0)

与接受的答案类似。尽管可以接受使用比较实现绝对值,但也更容易出现溢出:

print((sqrt(Number * Number)+ x)/ 2);

答案 5 :(得分:-2)

假设C或C ++:

switch ((unsigned long)Number & ~(unsigned long)LONG_MAX) {
    case 0:
        printf("%d\n", Number);
        break;
    default:
        printf("0\n", Number);
        break;
}

如果你认为switch是一个条件运算符,那么试试这个:

unsigned long flag = (unsigned long)Number & ~(unsigned long)LONG_MAX;
flag /= (unsigned long)LONG_MAX + 1;
flag = 1 - flag;
printf("%d\n", Number * flag);