Chinaunix

标题: 不用判断语句,求两个数的最大值 [打印本页]

作者: HappyWin    时间: 2004-10-11 15:53
标题: 不用判断语句,求两个数的最大值
两个int类型的数据,不用任何的判断语句如if、switch、?:等,找出其中的大值
作者: aero    时间: 2004-10-11 16:27
标题: 不用判断语句,求两个数的最大值
不可能吧?
程序三种结构:顺序、选择、循环。
没有判断,就不可能有选择和循环。
那么我就顺序执行程序吧。顺序执行就必然只有一个确定的结果。如果让程序判断两个数的大小,必然是要输出两个可能的结果才对。矛盾!
所以,偶认为不可能!
作者: HappyWin    时间: 2004-10-11 16:37
标题: 不用判断语句,求两个数的最大值
这是一道面试题目,没做出来,唉,偶也想不通
作者: aero    时间: 2004-10-11 16:45
标题: 不用判断语句,求两个数的最大值
那你没问面试你的人答案啊?
我想,起码里面得有隐含的判断。
作者: sprinklexu    时间: 2004-10-11 16:55
标题: 不用判断语句,求两个数的最大值
不知道下面这个样子行不行??



  1. main(){
  2. while(num1/num2 >;= 1){
  3. printf("num1 bigger than or equal to num2\n");
  4. goto out;
  5. }
  6. printf("num1 smaller than num2\n");

  7. out:
  8. exit(0);

  9. }
复制代码

作者: aero    时间: 2004-10-11 16:58
标题: 不用判断语句,求两个数的最大值
while里面不就是隐含的判断循环条件吗?
作者: 缘来缘散缘如水    时间: 2004-10-11 17:23
标题: 不用判断语句,求两个数的最大值
老天,这不是脑筋急转弯吧?从逻辑上讲,既然有“大”值,那就肯定有“小”值,相对论嘛;既然要分“大”和“小”,那就肯定要比较;既然要比较,不判断怎么能得出结果呢?

呢这不算灌水吧??
作者: A0110A    时间: 2004-10-11 17:43
标题: 不用判断语句,求两个数的最大值
写了一个感觉不好。

  1. int
  2. max(int x,int y)
  3. {
  4. int buf[2]={x,y};
  5. unsigned int z;

  6.         z=x-y;
  7.         z>;>;=31;

  8. return buf[z];
  9. }

复制代码

作者: sega6666    时间: 2004-10-11 18:13
标题: 不用判断语句,求两个数的最大值
面试还有这样的题!你回答什么了?如果说不可能,是不是就被拒绝了!
作者: 紫云飞扬    时间: 2004-10-11 19:29
标题: 不用判断语句,求两个数的最大值
用printf将两个int数据打印出来。
然后你盯着屏幕很容易找出较大的那个的。
作者: aero    时间: 2004-10-11 19:35
标题: 不用判断语句,求两个数的最大值
A0110A写的程序对。真NB!佩服!收藏!绝对收藏!

是了,一般奇妙的运算都是出在位运算上。开始我也是想看位运算能不能解决。结果太过相信自己的逻辑分析了。

用一个z的取值实现判断,其实是一个hash的过程。其实还是判断,我推论的还是没错,没判断是不成的,只是判断在什么位置。但程序真的很NB。估计这个就是答案的程序了。
作者: aero    时间: 2004-10-11 19:37
标题: 不用判断语句,求两个数的最大值
原帖由 "紫云飞扬" 发表:
用printf将两个int数据打印出来。
然后你盯着屏幕很容易找出较大的那个的。


这个……人脑与电脑的有机结合,最强!
作者: dj_ukyo    时间: 2004-10-11 19:47
标题: 不用判断语句,求两个数的最大值
的确赞同A0110A
作者: dj_ukyo    时间: 2004-10-11 20:12
标题: 不用判断语句,求两个数的最大值
明白了,关键就是取符号
作者: aspbiz    时间: 2004-10-11 20:35
标题: 不用判断语句,求两个数的最大值
厉害。
作者: HappyWin    时间: 2004-10-11 22:18
标题: 不用判断语句,求两个数的最大值
厉害,果然牛人也,
能不能讲讲z = z >;>; 31;怎么理解?
unsigned int z,z是无符号数,z=x-y;右移31位后剩下什么呢?
作者: HappyWin    时间: 2004-10-11 22:35
标题: 不用判断语句,求两个数的最大值

作者: win_hate    时间: 2004-10-11 23:06
标题: 不用判断语句,求两个数的最大值
我也有一个版本,可以直接算出来


  1. #include <stdio.h>;

  2. int
  3. main ()
  4. {
  5.         int x, y;

  6.         x = 0x4;
  7.         y = 0x4;
  8.         printf ("max of %d, %d is %d\n", x, y, new_max (x, y));
  9. }

  10. int
  11. new_max (int x, int y)
  12. {
  13.         int xy, yx;

  14.         xy = ((x - y) >;>; 31) & 1;
  15.         yx = ((y - x) >;>; 31) & 1;
  16.         return xy * y + yx * x + (1 - xy - yx) * x;
  17. }
复制代码

作者: FH    时间: 2004-10-11 23:57
标题: 不用判断语句,求两个数的最大值
A0110A的对么?一个很大的正数和一个很小的负数比较会得什么?
用8位来看吧:127-(-12=-1,由于高位是1,所以该函数返回-128!
作者: win_hate    时间: 2004-10-12 00:15
标题: 不用判断语句,求两个数的最大值
FH 说得对, 减法也会溢出。我的版本有相同的问题。
作者: win_hate    时间: 2004-10-12 01:19
标题: 不用判断语句,求两个数的最大值

  1. int
  2. new_max (int a, int b)
  3. {
  4.         return (a>;=b)*a + (a<b)*b;
  5. }
复制代码


这次应该行了
如果还有错........我就放弃了   
作者: birdielu    时间: 2004-10-12 02:11
标题: 不用判断语句,求两个数的最大值
恩,办法是人想出来的, 只有想不到的, 没有做不到的!
作者: flag    时间: 2004-10-12 08:33
标题: 不用判断语句,求两个数的最大值
原帖由 "FH" 发表:
A0110A的对么?一个很大的正数和一个很小的负数比较会得什么?
用8位来看吧:127-(-12=-1,由于高位是1,所以该函数返回-128!


避免溢出的话,对要求不做判断得出结果来说要求太高吧。要不加一层try{}catch{}?
作者: spring2spring    时间: 2004-10-12 09:02
标题: 不用判断语句,求两个数的最大值
这样如何?

int
new_max (int a, int b)
{
        return  a>;b?a:b;
}
作者: aero    时间: 2004-10-12 09:12
标题: 不用判断语句,求两个数的最大值
原帖由 "spring2spring" 发表:
这样如何?

int
new_max (int a, int b)
{
        return  a>;b?a:b;
}


当然不行,题目说的好好的。
作者: A0110A    时间: 2004-10-12 09:12
标题: 不用判断语句,求两个数的最大值
呵呵。如果要避免溢出的话简单点就要把存放计算结果的提高一个级别了。
当然不提高也可以,但是会繁一点 。
作者: FH    时间: 2004-10-12 09:18
标题: 不用判断语句,求两个数的最大值
  1. typedef        int        T_NUM;

  2. #define        SHIFTBITS        ( sizeof( T_NUM ) * 8 - 1 )

  3. static        int        CheckFlag( T_NUM x, T_NUM y )
  4. {
  5.         int        s1 = x >;>; SHIFTBITS;
  6.         int        s2 = y >;>; SHIFTBITS;

  7.         return ( s1 * 2 + s2 );
  8. }

  9. static        T_NUM        SameSign( int Flag, T_NUM x, T_NUM y )
  10. {
  11.         T_NUM        z = x - y;
  12.         T_NUM        t[2] = { x, y };
  13.         int        s = z >;>; SHIFTBITS;

  14.         return t[s];
  15. }

  16. static        T_NUM        DiffSign( int Flag, T_NUM x, T_NUM y )
  17. {
  18.         T_NUM        t[2] = { x, y };

  19.         return t[Flag - 1];
  20. }

  21. static        (*T_NUM)( int, T_NUM, T_NUM )        FuncList[] = {
  22.         SameSign, DiffSign, DiffSign, SameSign
  23. };

  24. T_NUM        Max( T_NUM x, T_NUM y )
  25. {
  26.         int        Flag = CheckFlag( x, y );

  27.         return (*FuncList[Flag])( Flag, x, y );
  28. }
复制代码

作者: wg0124    时间: 2004-10-12 09:25
标题: 不用判断语句,求两个数的最大值
看清楚他的要求就是不用任何的判断语句如if、switch、?:等,找出其中的大值。
    如果我的理解没有问题的话,大于号应该不是判断吧(是比较,嘿嘿)。那问题就该是如此简单啊。
main()
{
int a[2]={129,17},f;
f=a[1]>;a[0];
printf("%d\n",a[f]);
}

注:数组思想来自上面各位老大的帖子。
作者: win_hate    时间: 2004-10-12 10:01
标题: 不用判断语句,求两个数的最大值
FH 的方法没有使用逻辑表达式和判断语句,整个过程有点布电路的感觉,很精彩。


ps>; 我的 PM 有问题,以后回复你。
作者: JohnBull    时间: 2004-10-12 12:21
标题: 不用判断语句,求两个数的最大值
max(a,b)=((a+b)+abs(a-b))/2
min(a,b)=((a+b)-abs(a-b))/2
作者: aero    时间: 2004-10-12 12:26
标题: 不用判断语句,求两个数的最大值
^_^,老大,abs的运算不用到判断吗?
作者: win_hate    时间: 2004-10-12 12:33
标题: 不用判断语句,求两个数的最大值
abs 可以看成黑盒,但那个方法会溢出。
作者: JohnBull    时间: 2004-10-12 12:40
标题: 不用判断语句,求两个数的最大值
[quote]原帖由 "aero"]^_^,老大,abs的运算不用到判断吗?[/quote 发表:



库里面实现也算?那肯定不可能实现,任何一个系统调用都有数不清的判断.  
作者: win_hate    时间: 2004-10-12 12:41
标题: 不用判断语句,求两个数的最大值
to FH:

我的 PM 还是不能用。

你好象是说我的第二个版本使用了比较。我的看法如下:

比较与判断是不同的, a>;b 是一个逻辑表达式,而 ? : 是条件表达式。按我理解的题意,不能用的是后者。可以用汇编来说明一下,cmp 是个比较,其后的 jne 之类的语句才是判断。

如果连逻辑表达式也不能用,那只有你给出的代码完全可用。

但我估计题意是允许使用 逻辑表达式 的。
作者: rollingpig    时间: 2004-10-12 13:14
标题: 不用判断语句,求两个数的最大值
abs是正解吧
作者: rollingpig    时间: 2004-10-12 13:19
标题: 不用判断语句,求两个数的最大值
我觉得题的愿意就是考考数学思维
更为显得太复杂的!
作者: FH    时间: 2004-10-12 13:26
标题: 不用判断语句,求两个数的最大值
to win_hate:
同意,是我当初没看清楚题目。
另外,同意你所说的abs溢出问题。

使用逻辑表达式,wg0124的思路很好。
作者: BetonArmEE    时间: 2004-10-12 14:45
提示: 作者被禁止或删除 内容自动屏蔽
作者: FH    时间: 2004-10-12 14:50
标题: 不用判断语句,求两个数的最大值
楼上的问题:
b==a时被0除了
abs的溢出/fabs的误差
作者: 阿Benni    时间: 2004-10-12 15:10
标题: 不用判断语句,求两个数的最大值
ding
作者: 缘来缘散缘如水    时间: 2004-10-12 15:33
标题: 不用判断语句,求两个数的最大值
A0110A:C语言兼计算机专家;
JohnBull:数学家!


看了此贴,才知道高手的含义,才知道自己水平是何等地低
作者: sega6666    时间: 2004-10-12 16:00
标题: 不用判断语句,求两个数的最大值
无语,这么强!
作者: A0110A    时间: 2004-10-12 17:14
标题: 不用判断语句,求两个数的最大值
上来看看讨论这么热烈,我把没有缓冲溢出问题的代码贴出来,大家帮忙看看还有没有什么bug?

  1. 提升保存结果的方法如下:

  2. int
  3. max(int x,int y)
  4. {
  5. int buf[2]={x,y};
  6. unsigned long long z;

  7.         z=x-y;
  8.         z>;>;=63;

  9. return buf[z];
  10. }

  11. 不提升如下:
  12. int
  13. max(int x,int y)
  14. {
  15. int buf[2]={x,y};
  16. unsigned int z;
  17. int c;  
  18.         
  19.         z=x-y;
  20.         c=x-y;
  21.         z>;>;=31;
  22.         z= ((x-c-y)&&1)^z;
  23.       
  24. return buf[z];
  25. }


复制代码

作者: FH    时间: 2004-10-12 17:28
标题: 不用判断语句,求两个数的最大值
楼上的自己测过么?(x-c-y)不是0么?
作者: daniel-hou    时间: 2004-10-12 17:56
标题: 不用判断语句,求两个数的最大值
A0110A兄弟真NB, 佩服!!!
作者: A0110A    时间: 2004-10-12 17:57
标题: 不用判断语句,求两个数的最大值
我只是选择性地测了一下,在x-y溢出后就不会为0。
作者: 流川    时间: 2004-10-12 18:13
标题: 不用判断语句,求两个数的最大值
高手!

都在这里!
作者: supercctv    时间: 2004-10-12 18:15
标题: 不用判断语句,求两个数的最大值
肯定要用位运算,
作者: daniel-hou    时间: 2004-10-12 18:31
标题: 不用判断语句,求两个数的最大值
z= ((x-c-y)&&1)^z;
估计是为了防此buf[]越界,直接改为
z=0^z;
作者: win_hate    时间: 2004-10-12 19:22
标题: 不用判断语句,求两个数的最大值
原帖由 "A0110A"]我只是选择性地测了一下,在x-y溢出后就不会为0。[/quote 发表:


这是不可能的。

[quote]原帖由 "A0110A" 发表:

  1. int
  2. max(int x,int y)
  3. {
  4. int buf[2]={x,y};
  5. unsigned int z;
  6. int c;
  7.       
  8.         z=x-y;
  9.         c=x-y;
  10.         z>;>;=31;
  11.         z= ((x-c-y)&&1)^z;
  12.       
  13. return buf[z];
  14. }
复制代码


x - c - y  =  x - y  -  c  =  c  -  c = 0


你不能假定次序,标准没有规定次序,次序由编译器决定
无论何种运算次序,结果都是 0。在 X86 上,无论你用 signed 还是 unsigned , cup 里进行的实际是 mod 2^32 的运算(环 Z/(2^32))。上述运算结果必定为0。
作者: win_hate    时间: 2004-10-12 19:26
标题: 不用判断语句,求两个数的最大值

  1. int
  2. main ()
  3. {
  4.         int x, y;

  5.         x = 0x7fffffff;
  6.         y = 0x80000000;
  7.         printf ("max of %d, %d is %d\n", x, y, max (x, y));
  8. }

  9. int
  10. max (int x, int y)
  11. {
  12.         int buf[2] = { x, y };
  13.         unsigned int z;
  14.         int c;

  15.         z = x - y;
  16.         c = x - y;
  17.         z >;>;= 31;
  18.         z = ((x - c - y) && 1) ^ z;

  19.         return buf[z];
  20. }
复制代码


上面是我对 A0110A  第三个版本写的测试代码,运行结果为
max of 2147483647, -2147483648 is -2147483648


ps>;  A0110A 的第2个代码很好的, 第1个代码也给大家指出了一个方向。谢谢A0110A。
作者: yuxh    时间: 2004-10-12 19:50
标题: 不用判断语句,求两个数的最大值
这个不会溢出.
  1. int max(int x,int y)
  2. {
  3.     int buf[2]={x,y};
  4.     unsigned int z;

  5.     z=(((1-((x^y)>;>;31)&1)*(x-y))>;>;31)&1;
  6.     z+=(((x^y)>;>;31)&1)*((x>;>;31)&1);

  7.     return buf[z];
  8. }
  9. main()
  10. {
  11.     int x, y;
  12.     printf("ENTER:");
  13.     scanf("%d,%d", &x, &y);
  14.     printf("x=%d, y=%d\n", x, y);
  15.     printf("MAX=%d\n", max(x, y));
  16. }
复制代码

作者: svenwang    时间: 2004-10-13 02:13
标题: 不用判断语句,求两个数的最大值
int max(int a, int b)
{
        int pair[2] = {a, b};
        return pair[a < b];
}
作者: A0110A    时间: 2004-10-13 08:49
标题: 不用判断语句,求两个数的最大值
原帖由 "daniel-hou" 发表:
接改为
z=0^z;


是用来判断计算有没有溢出,如果溢出了就改变一下索引值。
作者: A0110A    时间: 2004-10-13 08:53
标题: 不用判断语句,求两个数的最大值
原帖由 "win_hate" 发表:

max of 2147483647, -2147483648 is -2147483648
ps>;  A0110A 的第2个代码很好的, 第1个代码也给大家指出了一个方向。谢谢A0110A。


呵呵,谢啥,我来测试一下。
作者: A0110A    时间: 2004-10-13 09:31
标题: 不用判断语句,求两个数的最大值
呵呵,不错,一直没注意这个,上面有位兄弟提到了,可惜我没仔细看大家的回帖,应该所有的都存在这个问题,看来程序化中还要在家一句话。
作者: linux_newbie    时间: 2004-10-13 12:43
标题: 不用判断语句,求两个数的最大值
   好久没有来了。我也凑个热闹。

按照A0110A 的思路,将两个数相减,在-1为补码的机器上,如果最高位为1表示负数,否则为0或者正数。那么这个数并上0x80000000后再位移31位得到either 0 or 1,作为数组下标取得最大值。


int Max( int x, int y)
{
  int num[2] = {x, y};

  //if x >;= y, then idx = 0, else idx = 1
  int idx = ((x - y) & 0x80000000) >;>; 31;

  return num[idx];
}
作者: FH    时间: 2004-10-13 13:01
标题: 不用判断语句,求两个数的最大值
楼上的别添乱了,前边已经说过多次溢出的问题了,你没看?
作者: Moonwellatg4    时间: 2004-10-13 13:21
标题: 不用判断语句,求两个数的最大值
用unsigned __int64  来判断 两个int的数就没问题了 :)
作者: Clement_Yin    时间: 2004-10-13 13:50
标题: 不用判断语句,求两个数的最大值
pf! 太强了!
作者: linux_newbie    时间: 2004-10-13 13:52
标题: 不用判断语句,求两个数的最大值
[quote]原帖由 "FH"]楼上的别添乱了,前边已经说过多次溢出的问题了,你没看?[/quote 发表:


哈哈,确实如此。再来一个。
上面那个算法有问题,由于直接调用了减法表达式,因此会出现溢出。
下面这个是修正的算法:
将一个int分成两部分,最高位为符号位,剩下的31位为负载部分。
符号位通过signed_bit得出,为0(如果>;=0)或者为1(< 0)
负载部分通过value_stuff得出,介于0到0x7FFFFFFF之间,总为正数。
value_diff宏将两个数的负载部分进行减法运算(由于负载在0-0x7FFFFFFF之间且总为正数,因此不可能溢出),为0表示计算后的结果为正数,则x的负载大于或者等于y,否则x的负载小于y。

然后预先建立一个3维数组:
对于的维分别代表:

signed_bit(x), signed_bit(y), value_diff(x, y)

然后给这个数组初始化:

x,                //000 x为正数,y为正数,x负载>;=y, 那么x为最大值
y,                //001 x为正数,y为正数,x负载<y, 那么y为最大值
x,                //010 x为正数,y为负数,那么x为最大值 (无需考虑负载部分)
x,                //011 x为正数,y为负数,那么x为最大值(无需考虑负载部分)
y,                //100 x为负数,y为正数,那么y为最大值(无需考虑负载部分)
y,                //101 x为负数,y为正数,那么y为最大值(无需考虑负载部分)
x,                //110 x为负数,y为负数,x负载>;=y, 那么x为最大值
y                //111 x为负数,y为负数,x负载<y, 那么y为最大值

剩下就是分别得到3个维的index,并返回数组中的值。



  1. #define signed_bit(x) (( (x) & 0x80000000) >;>; 31)
  2. #define value_stuff(x)     ( x & 0x7FFFFFFF)

  3. #define value_diff(x, y) signed_bit( value_stuff(x) - value_stuff(y) )


  4. int Max( int x, int y)
  5. {
  6.   int nums[2][2][2] =
  7.   {
  8.                 x,                //000
  9.                 y,                //001
  10.                 x,                //010
  11.                 x,                //011
  12.                 y,                //100
  13.                 y,                //101
  14.                 x,                //110
  15.                 y                //111
  16.   };


  17.   int idx0 = signed_bit(x);
  18.   int idx1 = signed_bit(y);
  19.   int idx2 = value_diff(x, y);

  20.   return nums[idx0][idx1][idx2];
  21. }
复制代码

作者: JohnBull    时间: 2004-10-13 13:57
标题: 不用判断语句,求两个数的最大值
原帖由 "svenwang" 发表:
int max(int a, int b)
{
int pair[2] = {a, b};
return pair[a < b];
}


I like this answer.
作者: ecloud    时间: 2004-10-13 16:40
标题: 不用判断语句,求两个数的最大值
楼上的,你认为出现一个“<”复合题意吗?
我觉得这个不行,由于C中使用数字作为真假,所以只要有任何得比较运算符就可以理解为做了判断
我觉得svenwang的方法有点偷换概念了
个人认为:
位运算由于硬件体制的问题,难免出现各种溢出现象
还是FH的模拟电路方法是正解,不知道CPU中的比较门电路的数学原型是不是就是这个样子的
估计这个面试单位是Intel的核心开发部 -_-!
作者: cellar    时间: 2004-10-14 09:53
标题: 不用判断语句,求两个数的最大值
70年代 09:47:12
两个int类型的数据,不用任何的判断语句如if、switch、?:等,找出其中的大值
面试题,你答一下
蚊见蚊爱 09:48:50
考,这是编程的艺术上的课后题
蚊见蚊爱 09:48:57
用绝对值做
蚊见蚊爱 09:49:04
27分难度
蚊见蚊爱 09:49:24
绝对值函数就是一个if的组合函数
蚊见蚊爱 09:49:34
还有什么话说?
70年代 09:49:24
具体说说
蚊见蚊爱 09:52:04
x/2+y/2+abs(x/2-y/2)
作者: yuxh    时间: 2004-10-14 10:22
标题: 不用判断语句,求两个数的最大值
1、在不考虑溢出的情况下,unsigned int z=((x-y)>;>;31)&1的值有两种可能,x>;=y时为0,x<y时为1,所以当x>;=y时(1-z)*x+z*y的值为x,当x<y时其值为y,所以(1-z)*x+z*y就是x,y的最大值。函数如下:
  1. int max(int x,int y)
  2. {
  3.     unsigned int z;

  4.     z=((x-y)>;>;31)&1;

  5.     return (1-z)*x+z*y;
  6. }
复制代码


2、在考虑溢出的情况下,unsigned int z=((x^y)>;>;31)&1的值有两种可能,x、y同号时为0,x、y异号时为1。当x、y同号时x-y不会溢出,可参考1,得出最大值;当x、y异号时,取正的那个就是最大值。函数如下:
  1. int max1(int x,int y)
  2. {
  3.     unsigned int z;

  4.     z=((x-y)>;>;31)&1;

  5.     return (1-z)*x+z*y;
  6. }

  7. int max2(int x, int y)
  8. {
  9.     unsigned int z;

  10.     z=(x>;>;31)&1;
  11.     return (1-z)*x + z*y;
  12. }

  13. int max(int x, int y)
  14. {
  15.     unsigned int z;

  16.     z=((x^y)>;>;31)&1;
  17.     return (1-z)*max1(x,y) + z*max2(x,y);
  18. }
复制代码

作者: yuxh    时间: 2004-10-14 10:25
标题: 不用判断语句,求两个数的最大值
若用A0110A 的思路,则我前面写的那个函数也不会有溢出的问题,同样是考虑了同号和异号的情况。
作者: river_wave    时间: 2004-10-14 10:28
标题: 不用判断语句,求两个数的最大值
int max(int x,int y)
{
    int a[2];
    int sign;

    a[0]=x;
    a[1]=y;
    //改语句判断x,y大小,sign为0表示x>;y,sign为1表示x<y
    sign=((x-y)&0x80000000)>;>;31;

    printf("sign=%d,a[0]=%d,a[1]=%d\n",sign,a[0],a[1]);

    return a[sign];
}
作者: win_hate    时间: 2004-10-14 11:09
标题: 不用判断语句,求两个数的最大值
一个不用逻辑表达式,基于插值的方法:


  1. int max (int a, int b)
  2. {
  3.         int g, r1, r2;

  4.         g = ((a^b) >;>; 31) & 1;
  5.         r1 = (a >;>; 31) & 1;
  6.         r2 = ((a-b) >;>; 31) & 1;

  7.         return g*(r1*b + (1-r1)*a) + (1-g)*(r2*b + (1-r2)*a);
  8. }
复制代码

作者: win_hate    时间: 2004-10-14 11:11
标题: 不用判断语句,求两个数的最大值
这个贴子顶这么长了,我对上面出现的解决方法做一个总结。

问题:int a, b; 求 max (a,b),不能用判断语句。

一、寻找最大数的根据:

1、允许用逻辑表达式:
        利用逻辑表达式的值, {a>;=b、a<b} = {0,1}。
2、不允许用逻辑表达式:
        利用比特位

        a^b 的最高位 ---- 判断符号是否相等
        a-b 的最高位 ---- 在符号相同的情况下判断大小
        a   的最高位 ---- a的符号
        b   的最高位 ---- b的符号

二、对上述标准的应用:

1、把大小关系对应到一个或若干个矩阵当中

        在本贴中,这个想法最早可以从 A0110A 的贴子中看到,但那段代码有点瑕疵。
       
        wg0124, svenwang 基于逻辑表达式构造了简单的对应关系。

        在不允许使用逻辑表达式的情况下,FH 和 linuxnewbie 仍然能实现对应。FH 和 linuxnewbie 的方法都可视力为A0110A方法的一个扩展。其中linuxnewbie的对应方法很直接,而且有注释,应该容易理解。FH 的方法我略微解释一下,在同号的情况下,FH 先把 a,b 的符号对应为 01 或 10,这正好是 2, 1,然后再把大小关系对应到一个矩阵中去。


2、使用插值

        yuxh和本人 给出的方法均基于插值。

        注意到无论是否使用逻辑表达式,我们的判定依据都是若干bit,当它们取不同值的时候,映射为不同值。从数学上看,这就是个插值问题。

三、只从数学上考虑:

        单纯出于数学上的考虑,不管计算机本身的限制, JohnBull 版主给出了两个公式,该公式刻画了max, min 与 绝对值的关系。有兴趣的朋友可以自行推导一下。如果推导有困难,可以查阅与“数学分析”相关的书。
作者: cellar    时间: 2004-10-14 15:36
标题: 不用判断语句,求两个数的最大值
差不多了吧?再来!
不用循环求一个整数是否为2的n次幂 n<=31
作者: FH    时间: 2004-10-14 16:46
标题: 不用判断语句,求两个数的最大值
另起一贴吧
作者: 白色乌鸦    时间: 2004-10-15 10:32
标题: 不用判断语句,求两个数的最大值
x/2+y/2+abs(x/2-y/2)

^_^  pf
作者: FH    时间: 2004-10-15 14:50
标题: 不用判断语句,求两个数的最大值
还在做么?别忘了x,y都是整数,数学上对的电脑上不一定对!
楼上用1,3带进去试试看。别忘了,1/2=0,3/2=1。
作者: netchong    时间: 2004-10-15 15:05
提示: 作者被禁止或删除 内容自动屏蔽
作者: FH    时间: 2004-10-15 15:08
标题: 不用判断语句,求两个数的最大值
楼上的,问题是用1/2就可以避免溢出。
作者: zerglot    时间: 2004-10-15 15:55
标题: 不用判断语句,求两个数的最大值
想不明白
作者: xtiawy    时间: 2004-10-15 23:32
标题: 不用判断语句,求两个数的最大值
4
9
13+5=18/2=9


4
-9

4+(-13)=-9
-5+13=8/2

3
7
10+4=14/2

-2
9
7+11=18/2

2
9
11+7=18/2

-7
-9
-16-2=-18/2

7
9
16+2=18/2

0
0
0+0=0/2
out:
z=x+y+(-1*(x-y))
max=z/2
好久没接触程序了,代码都忘得差不多了,不过算法永远都不会忘的,数学的魅力是如此吸引人!!
作者: fraskey    时间: 2004-10-16 20:59
标题: 不用判断语句,求两个数的最大值
如果a,b都不为零的话:return ((a/b)*a+(b/a)*b)/(a/b+b/a);
呵呵
作者: lhy7879    时间: 2004-10-17 20:35
标题: 不用判断语句,求两个数的最大值
int max(int a,int b)
{
        int e[3];
        int i;

        e[0] = b;
        e[2] = a;

        i = (((a-b)-(b-a))+1)%2;
        return( e[i+1]);
}

一定可以。
作者: FH    时间: 2004-10-18 09:55
标题: 不用判断语句,求两个数的最大值
楼上的验算过么?i永远是1吧?
作者: lhy7879    时间: 2004-10-18 12:21
标题: 不用判断语句,求两个数的最大值
请看清楚
(a-b)-(b-a)除了0之外,要莫是负数的2的倍数,要么是正数的2的倍数

负的2的倍数+1取2的余数一定是-1啊

然后其它就不要我说了吧
作者: FH    时间: 2004-10-18 14:29
标题: 不用判断语句,求两个数的最大值
呵呵,还是用127和-128验证一下8位的情况就知道了。
请楼上的作者自己验算一下。
作者: lhy7879    时间: 2004-10-18 15:17
标题: 不用判断语句,求两个数的最大值
原帖由 "FH" 发表:
呵呵,还是用127和-128验证一下8位的情况就知道了。
请楼上的作者自己验算一下。


我在sco-unix 5.05下运行是一定没有问题的。相信在其它unix环境也不会有问题。

换个写法:
i = (2*(a-b) + 1)/2

呵呵,这种写法,楼上的一看就清楚了吧
a-b小于0时返回-1
a-b大于等于0时返回+1

做程序你不可能让带入的参数a和b恶意越界吧。
      
作者: lhy7879    时间: 2004-10-18 15:19
标题: 不用判断语句,求两个数的最大值
i = (2*(a-b) + 1)%2
写错了,不好意思
作者: FH    时间: 2004-10-18 15:39
标题: 不用判断语句,求两个数的最大值
楼上的,什么叫恶意越界啊?你的程序是给别人用的还是给自己玩的?不做临界测试怎么知道正确性呢?那不越界不就是自己哄着自己玩么?
作者: 风花树    时间: 2004-10-18 16:28
标题: 不用判断语句,求两个数的最大值
这还不简单,把代码自己去试试就行了。不行就把不行的结果贴不出。大家一看就明白。光说也没有用啊
作者: dysnake    时间: 2004-10-18 17:13
标题: 不用判断语句,求两个数的最大值

  1. #include <stdio.h>;

  2. #define new_max(x, y, z) z = x - y, (z = (*((unsigned int *)&z) >;>; 31) & 1)

  3. int main(void)
  4. {
  5.         int x, y, z;

  6.         x = -100;
  7.         y = 10;
  8.         new_max(x, y, z);
  9.         printf("max = [%d]\n", (1 - z) * x + z * y);
  10. }
复制代码

我觉得可以用指针类型的强制转换来防止溢出问题,实验了一下可以的.
作者: FH    时间: 2004-10-18 17:24
标题: 不用判断语句,求两个数的最大值
[quote]原帖由 "dysnake"]我觉得可以用指针类型的强制转换来防止溢出问题,实验了一下可以的.[/quote 发表:

呵呵,很幽默!不知道试验是怎么做的。是用0x7FFFFFFF-0x80000000么?
作者: Moonwellatg4    时间: 2004-10-18 17:31
标题: 不用判断语句,求两个数的最大值
呵呵,居然还有那么多人在研究这个问题啊!

只要用到了相减,肯定会存在越界的问题。

估计只能这么解决了
int run(int num1,int num2)
{
__int64 a[2];
a[0] = num1;
a[1] = num2;
..............
...........
........

}
作者: doublefox    时间: 2004-10-22 10:59
标题: 不用判断语句,求两个数的最大值
max(int a, int b)
{
    return((a+b)/2+abs((a-b+1)/2));
}

应该就这么简单吧!
作者: robinliu76    时间: 2004-11-05 13:33
标题: 不用判断语句,求两个数的最大值
谢谢!!
作者: cornia    时间: 2004-11-05 17:09
标题: 不用判断语句,求两个数的最大值
确实长知识啦,谢谢!
作者: jixunuli    时间: 2004-11-05 21:34
标题: 不用判断语句,求两个数的最大值
$ man min
作者: colinfei    时间: 2004-11-09 21:38
标题: 不用判断语句,求两个数的最大值
看来还是要学好数据结构呀!
作者: gsyeye    时间: 2004-12-23 19:28
标题: 不用判断语句,求两个数的最大值
高手阿……

佩服……

不佩服都不行啊
作者: bibi    时间: 2005-04-28 16:50
标题: 不用判断语句,求两个数的最大值
int max(int a, int b)
{
    return((a+b+abs(a-b))/2);
}
作者: mars198261    时间: 2005-04-28 17:26
标题: 不用判断语句,求两个数的最大值
没有判断,哪儿来的大小?
作者: rainshadow    时间: 2005-04-28 17:32
标题: 不用判断语句,求两个数的最大值
bibi正解
作者: Kevinkw    时间: 2005-04-28 20:25
标题: 不用判断语句,求两个数的最大值
请问怎么删除帖子?
作者: I love c too    时间: 2005-04-28 20:59
标题: 不用判断语句,求两个数的最大值
原帖由 "紫云飞扬" 发表:
用printf将两个int数据打印出来。
然后你盯着屏幕很容易找出较大的那个的。

哈哈,这个办法不错...




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2