2.23/7.19不用小学列算式 不用写答的另一种算法

每次从2、3、5、7、9中选四个数,写出五个两位数减两位数的退位减法算式,并计算. _百度作业帮
每次从2、3、5、7、9中选四个数,写出五个两位数减两位数的退位减法算式,并计算.
每次从2、3、5、7、9中选四个数,写出五个两位数减两位数的退位减法算式,并计算.&
35-27 37-25 57-32 53-27 52-37
采纳我的吧
下面那个是对的不用判断语句,求两个数的最大值
[精彩] 不用判断语句,求两个数的最大值
http://www.chinaunix.net 作者:&&发表于:
【】 【】 【】【关闭】
两个int类型的数据,不用任何的判断语句如if、switch、?:等,找出其中的大值
& 回复于: 16:27:56
不可能吧?
程序三种结构:顺序、选择、循环。
没有判断,就不可能有选择和循环。
那么我就顺序执行程序吧。顺序执行就必然只有一个确定的结果。如果让程序判断两个数的大小,必然是要输出两个可能的结果才对。矛盾!
所以,偶认为不可能!
& 回复于: 16:37:12
这是一道面试题目,没做出来,唉,偶也想不通
& 回复于: 16:45:04
那你没问面试你的人答案啊?
我想,起码里面得有隐含的判断。
& 回复于: 16:55:23
不知道下面这个样子行不行??
while(num1/num2&&;=&1){
printf("num1&bigger&than&or&equal&to&num2\n");
printf("num1&smaller&than&num2\n");
& 回复于: 16:58:46
while里面不就是隐含的判断循环条件吗?
& 回复于: 17:23:03
老天,这不是脑筋急转弯吧?从逻辑上讲,既然有“大”值,那就肯定有“小”值,相对论嘛;既然要分“大”和“小”,那就肯定要比较;既然要比较,不判断怎么能得出结果呢?
呢这不算灌水吧??
& 回复于: 17:43:57
写了一个感觉不好。
max(int&x,int&y)
int&buf[2]={x,y};
unsigned&int&z;
&&&&&&&&z=x-y;
&&&&&&&&z&;&;=31;
return&buf[z];
& 回复于: 18:13:12
面试还有这样的题!你回答什么了?如果说不可能,是不是就被拒绝了!
& 回复于: 19:29:36
用printf将两个int数据打印出来。
然后你盯着屏幕很容易找出较大的那个的。
& 回复于: 19:35:43
A0110A写的程序对。真NB!佩服!收藏!绝对收藏!
是了,一般奇妙的运算都是出在位运算上。开始我也是想看位运算能不能解决。结果太过相信自己的逻辑分析了。
用一个z的取值实现判断,其实是一个hash的过程。其实还是判断,我推论的还是没错,没判断是不成的,只是判断在什么位置。但程序真的很NB。估计这个就是答案的程序了。
& 回复于: 19:37:55
引用:原帖由&"紫云飞扬"&发表:
用printf将两个int数据打印出来。
然后你盯着屏幕很容易找出较大的那个的。
这个……人脑与电脑的有机结合,最强!
& 回复于: 19:47:00
的确赞同A0110A
& 回复于: 20:12:55
明白了,关键就是取符号
& 回复于: 20:35:54
& 回复于: 22:18:10
厉害,果然牛人也,
能不能讲讲z&=&z&&;&;&31;怎么理解?
unsigned&int&z,z是无符号数,z=x-y;右移31位后剩下什么呢?
& 回复于: 22:35:32
& 回复于: 23:06:53
我也有一个版本,可以直接算出来
#include&&stdio.h&;
&&&&&&&&int&x,&y;
&&&&&&&&x&=&0x4;
&&&&&&&&y&=&0x4;
&&&&&&&&printf&("max&of&%d,&%d&is&%d\n",&x,&y,&new_max&(x,&y));
new_max&(int&x,&int&y)
&&&&&&&&int&xy,&
&&&&&&&&xy&=&((x&-&y)&&;&;&31)&&&1;
&&&&&&&&yx&=&((y&-&x)&&;&;&31)&&&1;
&&&&&&&&return&xy&*&y&+&yx&*&x&+&(1&-&xy&-&yx)&*&x;
& 回复于: 23:57:26
A0110A的对么?一个很大的正数和一个很小的负数比较会得什么?
用8位来看吧:127-(-128)=-1,由于高位是1,所以该函数返回-128!
& 回复于: 00:15:51
FH&说得对,&减法也会溢出。我的版本有相同的问题。
& 回复于: 01:19:07
new_max&(int&a,&int&b)
&&&&&&&&return&(a&;=b)*a&+&(a&b)*b;
这次应该行了&:evil:
如果还有错........我就放弃了&&&:em06:
& 回复于: 02:11:29
恩,办法是人想出来的,&只有想不到的,&没有做不到的!
& 回复于: 08:33:56
引用:原帖由&"FH"&发表:
A0110A的对么?一个很大的正数和一个很小的负数比较会得什么?
用8位来看吧:127-(-128)=-1,由于高位是1,所以该函数返回-128!
避免溢出的话,对要求不做判断得出结果来说要求太高吧。要不加一层try{}catch{}?
& 回复于: 09:02:19
这样如何?
new_max&(int&a,&int&b)&
&&&&&&&&return&&a&;b?a:b;
& 回复于: 09:12:41
引用:原帖由&"spring2spring"&发表:
这样如何?
new_max&(int&a,&int&b)&
&&&&&&&&return&&a&;b?a:b;
当然不行,题目说的好好的。
& 回复于: 09:12:53
呵呵。如果要避免溢出的话简单点就要把存放计算结果的提高一个级别了。
当然不提高也可以,但是会繁一点&。
& 回复于: 09:18:04
(&sizeof(&T_NUM&)&*&8&-&1&)
CheckFlag(&T_NUM&x,&T_NUM&y&)
s1&=&x&&;&;&SHIFTBITS;
s2&=&y&&;&;&SHIFTBITS;
return&(&s1&*&2&+&s2&);
SameSign(&int&Flag,&T_NUM&x,&T_NUM&y&)
z&=&x&-&y;
t[2]&=&{&x,&y&};
s&=&z&&;&;&SHIFTBITS;
return&t[s];
DiffSign(&int&Flag,&T_NUM&x,&T_NUM&y&)
t[2]&=&{&x,&y&};
return&t[Flag&-&1];
(*T_NUM)(&int,&T_NUM,&T_NUM&)
FuncList[]&=&{
SameSign,&DiffSign,&DiffSign,&SameSign
Max(&T_NUM&x,&T_NUM&y&)
Flag&=&CheckFlag(&x,&y&);
return&(*FuncList[Flag])(&Flag,&x,&y&);
& 回复于: 09:25:18
看清楚他的要求就是不用任何的判断语句如if、switch、?:等,找出其中的大值。
&&&&如果我的理解没有问题的话,大于号应该不是判断吧(是比较,嘿嘿)。那问题就该是如此简单啊。
int&a[2]={129,17},f;
f=a[1]&;a[0];
printf("%d\n",a[f]);
注:数组思想来自上面各位老大的帖子。
& 回复于: 10:01:29
FH&的方法没有使用逻辑表达式和判断语句,整个过程有点布电路的感觉,很精彩。
ps&;&我的&PM&有问题,以后回复你。
& 回复于: 12:21:36
max(a,b)=((a+b)+abs(a-b))/2
min(a,b)=((a+b)-abs(a-b))/2
& 回复于: 12:26:16
^_^,老大,abs的运算不用到判断吗?
& 回复于: 12:33:13
abs&可以看成黑盒,但那个方法会溢出。
& 回复于: 12:40:17
引用:原帖由&"aero"]^_^,老大,abs的运算不用到判断吗?
库里面实现也算?那肯定不可能实现,任何一个系统调用都有数不清的判断.&&:|
& 回复于: 12:41:26
我的&PM&还是不能用。
你好象是说我的第二个版本使用了比较。我的看法如下:
比较与判断是不同的,&a&;b&是一个逻辑表达式,而&?&:&是条件表达式。按我理解的题意,不能用的是后者。可以用汇编来说明一下,cmp&是个比较,其后的&jne&之类的语句才是判断。
如果连逻辑表达式也不能用,那只有你给出的代码完全可用。
但我估计题意是允许使用&逻辑表达式&的。
& 回复于: 13:14:11
abs是正解吧
& 回复于: 13:19:04
我觉得题的愿意就是考考数学思维
更为显得太复杂的!
& 回复于: 13:26:10
to&win_hate:
同意,是我当初没看清楚题目。
另外,同意你所说的abs溢出问题。
使用逻辑表达式,wg0124的思路很好。
& 回复于: 14:45:06
呵呵,我来试试
----------------------------------------------
#include&&stdio.h&;
#include&&math.h&;
int&max(&int&a&,&int&b&)
int&buf[3];
buf[0]&=&a&;
buf[1]&=&0&;
buf[2]&=&b&;
max&=&buf[&(int)(&(&b&-&a&)&/&fabs(&b&-&a&)&+&1&)&]&;
int&main()
printf(&"max(&%d&,&%d&)&=&%d\n"&,&x&,&y&,&max(x,y)&);
& 回复于: 14:50:37
楼上的问题:
b==a时被0除了
abs的溢出/fabs的误差
& 回复于: 15:10:01
& 回复于: 15:33:33
A0110A:C语言兼计算机专家;
JohnBull:数学家!
看了此贴,才知道高手的含义,才知道自己水平是何等地低&:em16:
& 回复于: 16:00:29
无语,这么强!
& 回复于: 17:14:13
上来看看讨论这么热烈,我把没有缓冲溢出问题的代码贴出来,大家帮忙看看还有没有什么bug?
提升保存结果的方法如下:
max(int&x,int&y)
int&buf[2]={x,y};
unsigned&long&long&z;
&&&&&&&&z=x-y;
&&&&&&&&z&;&;=63;
return&buf[z];
不提升如下:
max(int&x,int&y)
int&buf[2]={x,y};
unsigned&int&z;
&&&&&&&&z=x-y;
&&&&&&&&c=x-y;
&&&&&&&&z&;&;=31;
&&&&&&&&z=&((x-c-y)&&1)^z;
return&buf[z];
& 回复于: 17:28:57
楼上的自己测过么?(x-c-y)不是0么?
& 回复于: 17:56:38
A0110A兄弟真NB,&佩服!!!&:em02:
& 回复于: 17:57:21
我只是选择性地测了一下,在x-y溢出后就不会为0。
& 回复于: 18:13:51
都在这里!
& 回复于: 18:15:56
肯定要用位运算,
& 回复于: 18:31:15
z=&((x-c-y)&&1)^z;
估计是为了防此buf[]越界,直接改为
& 回复于: 19:22:47
引用:原帖由&"A0110A"]我只是选择性地测了一下,在x-y溢出后就不会为0。
这是不可能的。
引用:原帖由&"A0110A"&发表:
max(int&x,int&y)
int&buf[2]={x,y};
unsigned&int&z;
&&&&&&&&z=x-y;
&&&&&&&&c=x-y;
&&&&&&&&z&;&;=31;
&&&&&&&&z=&((x-c-y)&&1)^z;
return&buf[z];
x&-&c&-&y&&=&&x&-&y&&-&&c&&=&&c&&-&&c&=&0
你不能假定次序,标准没有规定次序,次序由编译器决定
无论何种运算次序,结果都是&0。在&X86&上,无论你用&signed&还是&unsigned&,&cup&里进行的实际是&mod&2^32&的运算(环&Z/(2^32))。上述运算结果必定为0。
& 回复于: 19:26:49
&&&&&&&&int&x,&y;
&&&&&&&&x&=&0x7
&&&&&&&&y&=&0x;
&&&&&&&&printf&("max&of&%d,&%d&is&%d\n",&x,&y,&max&(x,&y));
max&(int&x,&int&y)
&&&&&&&&int&buf[2]&=&{&x,&y&};
&&&&&&&&unsigned&int&z;
&&&&&&&&int&c;
&&&&&&&&z&=&x&-&y;
&&&&&&&&c&=&x&-&y;
&&&&&&&&z&&;&;=&31;
&&&&&&&&z&=&((x&-&c&-&y)&&&&1)&^&z;
&&&&&&&&return&buf[z];
上面是我对&A0110A&&第三个版本写的测试代码,运行结果为
max&of&,&-&is&-
ps&;&&A0110A&的第2个代码很好的,&第1个代码也给大家指出了一个方向。谢谢A0110A。
& 回复于: 19:50:20
这个不会溢出.
int&max(int&x,int&y)
&&&&int&buf[2]={x,y};
&&&&unsigned&int&z;
&&&&z=(((1-((x^y)&;&;31)&1)*(x-y))&;&;31)&1;
&&&&z+=(((x^y)&;&;31)&1)*((x&;&;31)&1);
&&&&return&buf[z];
&&&&int&x,&y;
&&&&printf("ENTER:");
&&&&scanf("%d,%d",&&x,&&y);
&&&&printf("x=%d,&y=%d\n",&x,&y);
&&&&printf("MAX=%d\n",&max(x,&y));
& 回复于: 02:13:48
int&max(int&a,&int&b)
int&pair[2]&=&{a,&b};
return&pair[a&&&b];
& 回复于: 08:49:50
引用:原帖由&"daniel-hou"&发表:
是用来判断计算有没有溢出,如果溢出了就改变一下索引值。
& 回复于: 08:53:01
引用:原帖由&"win_hate"&发表:
max&of&,&-&is&-&
ps&;&&A0110A&的第2个代码很好的,&第1个代码也给大家指出了一个方向。谢谢A0110A。
呵呵,谢啥,我来测试一下。
& 回复于: 09:31:40
呵呵,不错,一直没注意这个,上面有位兄弟提到了,可惜我没仔细看大家的回帖,应该所有的都存在这个问题,看来程序化中还要在家一句话。
& 回复于: 12:43:27
:D&&:D&好久没有来了。我也凑个热闹。
按照A0110A&的思路,将两个数相减,在-1为补码的机器上,如果最高位为1表示负数,否则为0或者正数。那么这个数并上0x后再位移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)&&&0x)&&;&;&31;
&&return&num[idx];
& 回复于: 13:01:02
楼上的别添乱了,前边已经说过多次溢出的问题了,你没看?
& 回复于: 13:21:51
用unsigned&__int64&&来判断&两个int的数就没问题了&:)
& 回复于: 13:50:30
pf!&太强了!
& 回复于: 13:52:04
引用:原帖由&"FH"]楼上的别添乱了,前边已经说过多次溢出的问题了,你没看?
哈哈,确实如此。再来一个。
上面那个算法有问题,由于直接调用了减法表达式,因此会出现溢出。
下面这个是修正的算法:
将一个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)
然后给这个数组初始化:
//000&x为正数,y为正数,x负载&;=y,&那么x为最大值
//001&x为正数,y为正数,x负载&y,&那么y为最大值
//010&x为正数,y为负数,那么x为最大值&(无需考虑负载部分)
x, //011&x为正数,y为负数,那么x为最大值(无需考虑负载部分)
y, //100&x为负数,y为正数,那么y为最大值(无需考虑负载部分)
y, //101&x为负数,y为正数,那么y为最大值(无需考虑负载部分)
//110&x为负数,y为负数,x负载&;=y,&那么x为最大值
//111&x为负数,y为负数,x负载&y,&那么y为最大值
剩下就是分别得到3个维的index,并返回数组中的值。
#define&signed_bit(x)&((&(x)&&&0x)&&;&;&31)
#define&value_stuff(x)&&&&&(&x&&&0x7FFFFFFF)
#define&value_diff(x,&y)&signed_bit(&value_stuff(x)&-&value_stuff(y)&)
int&Max(&int&x,&int&y)
&&int&nums[2][2][2]&=&
&&int&idx0&=&signed_bit(x);
&&int&idx1&=&signed_bit(y);
&&int&idx2&=&value_diff(x,&y);
&&return&nums[idx0][idx1][idx2];
& 回复于: 13:57:30
引用:原帖由&"svenwang"&发表:
int&max(int&a,&int&b)
int&pair[2]&=&{a,&b};
return&pair[a&&&b];
I&like&this&answer.
& 回复于: 16:40:58
楼上的,你认为出现一个“&”复合题意吗?
我觉得这个不行,由于C中使用数字作为真假,所以只要有任何得比较运算符就可以理解为做了判断
我觉得svenwang的方法有点偷换概念了
个人认为:
位运算由于硬件体制的问题,难免出现各种溢出现象
还是FH的模拟电路方法是正解,不知道CPU中的比较门电路的数学原型是不是就是这个样子的
估计这个面试单位是Intel的核心开发部&-_-!
& 回复于: 09:53:52
70年代&09:47:12
两个int类型的数据,不用任何的判断语句如if、switch、?:等,找出其中的大值
面试题,你答一下&
蚊见蚊爱&09:48:50
考,这是编程的艺术上的课后题&
蚊见蚊爱&09:48:57
用绝对值做&
蚊见蚊爱&09:49:04
蚊见蚊爱&09:49:24
绝对值函数就是一个if的组合函数&
蚊见蚊爱&09:49:34
还有什么话说?
70年代&09:49:24
蚊见蚊爱&09:52:04
x/2+y/2+abs(x/2-y/2)
& 回复于: 10:22:54
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的
最大值。函数如下:
int&max(int&x,int&y)
&&&&unsigned&int&z;
&&&&z=((x-y)&;&;31)&1;
&&&&return&(1-z)*x+z*y;
2、在考虑溢出的情况下,unsigned&int&z=((x^y)&;&;31)&1的值有两种可能,x、y同号时为0,x、y异号时为1。当x、y同号时x-y不会溢出,可参考1,得出最大值;当x、y异号时,取正的那个就是最大值。函数如下:
int&max1(int&x,int&y)
&&&&unsigned&int&z;
&&&&z=((x-y)&;&;31)&1;
&&&&return&(1-z)*x+z*y;
int&max2(int&x,&int&y)
&&&&unsigned&int&z;
&&&&z=(x&;&;31)&1;
&&&&return&(1-z)*x&+&z*y;
int&max(int&x,&int&y)
&&&&unsigned&int&z;
&&&&z=((x^y)&;&;31)&1;
&&&&return&(1-z)*max1(x,y)&+&z*max2(x,y);
& 回复于: 10:25:55
若用A0110A&的思路,则我前面写的那个函数也不会有溢出的问题,同样是考虑了同号和异号的情况。
& 回复于: 10:28:04
int&max(int&x,int&y)
&&&&int&a[2];
&&&&a[0]=x;
&&&&a[1]=y;
&&&&//改语句判断x,y大小,sign为0表示x&;y,sign为1表示x&y
&&&&sign=((x-y)&0x)&;&;31;
&&&&printf("sign=%d,a[0]=%d,a[1]=%d\n",sign,a[0],a[1]);
&&&&return&a[sign];
& 回复于: 11:09:41
一个不用逻辑表达式,基于插值的方法:
int&max&(int&a,&int&b)
&&&&&&&&int&g,&r1,&r2;
&&&&&&&&g&=&((a^b)&&;&;&31)&&&1;
&&&&&&&&r1&=&(a&&;&;&31)&&&1;
&&&&&&&&r2&=&((a-b)&&;&;&31)&&&1;
&&&&&&&&return&g*(r1*b&+&(1-r1)*a)&+&(1-g)*(r2*b&+&(1-r2)*a);
& 回复于: 11:11:46
这个贴子顶这么长了,我对上面出现的解决方法做一个总结。
问题: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&与&绝对值的关系。有兴趣的朋友可以自行推导一下。如果推导有困难,可以查阅与“数学分析”相关的书。
& 回复于: 15:36:00
差不多了吧?再来!
不用循环求一个整数是否为2的n次幂&n&=31
& 回复于: 16:46:19
另起一贴吧
& 回复于: 10:32:04
x/2+y/2+abs(x/2-y/2)
& 回复于: 14:50:51
还在做么?别忘了x,y都是整数,数学上对的电脑上不一定对!
楼上用1,3带进去试试看。别忘了,1/2=0,3/2=1。
& 回复于: 15:05:24
引用:原帖由&"白色乌鸦"&发表:
x/2+y/2+abs(x/2-y/2)
在不考虑&x+y+abs(x-y)&会溢出的条件下,^_^,白色乌鸦的写法是可以的,改成这样:
(x&+&y&+&abs(x&-&y))/2
就会返回两个数中大的那个。
& 回复于: 15:08:52
楼上的,问题是用1/2就可以避免溢出。
& 回复于: 15:55:32
& 回复于: 23:32:29
13+5=18/2=9
4+(-13)=-9
-16-2=-18/2
z=x+y+(-1*(x-y))
好久没接触程序了,代码都忘得差不多了,不过算法永远都不会忘的,数学的魅力是如此吸引人!!
& 回复于: 20:59:11
如果a,b都不为零的话:return&((a/b)*a+(b/a)*b)/(a/b+b/a);
& 回复于: 20:35:49
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]);
一定可以。
& 回复于: 09:55:08
楼上的验算过么?i永远是1吧?
& 回复于: 12:21:38
(a-b)-(b-a)除了0之外,要莫是负数的2的倍数,要么是正数的2的倍数
负的2的倍数+1取2的余数一定是-1啊
然后其它就不要我说了吧
& 回复于: 14:29:25
呵呵,还是用127和-128验证一下8位的情况就知道了。
请楼上的作者自己验算一下。
& 回复于: 15:17:22
引用:原帖由&"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恶意越界吧。
&:lol:&&:lol:&&:lol:&&:lol:
& 回复于: 15:19:19
i&=&(2*(a-b)&+&1)%2&
写错了,不好意思
& 回复于: 15:39:54
楼上的,什么叫恶意越界啊?你的程序是给别人用的还是给自己玩的?不做临界测试怎么知道正确性呢?那不越界不就是自己哄着自己玩么?
& 回复于: 16:28:42
这还不简单,把代码自己去试试就行了。不行就把不行的结果贴不出。大家一看就明白。光说也没有用啊
& 回复于: 17:13:08
#include&&stdio.h&;
#define&new_max(x,&y,&z)&z&=&x&-&y,&(z&=&(*((unsigned&int&*)&z)&&;&;&31)&&&1)
int&main(void)
&&&&&&&&int&x,&y,&z;
&&&&&&&&x&=&-100;
&&&&&&&&y&=&10;
&&&&&&&&new_max(x,&y,&z);
&&&&&&&&printf("max&=&[%d]\n",&(1&-&z)&*&x&+&z&*&y);
我觉得可以用指针类型的强制转换来防止溢出问题,实验了一下可以的.
& 回复于: 17:24:07
引用:原帖由&"dysnake"]我觉得可以用指针类型的强制转换来防止溢出问题,实验了一下可以的.
呵呵,很幽默!不知道试验是怎么做的。是用0x7FFFFFFF-0x么?
& 回复于: 17:31:36
呵呵,居然还有那么多人在研究这个问题啊!
只要用到了相减,肯定会存在越界的问题。
估计只能这么解决了
int&run(int&num1,int&num2)
&__int64&a[2];
a[0]&=&num1;
a[1]&=&num2;
&..............
...........
& 回复于: 10:59:37
max(int&a,&int&b)
&&&&return((a+b)/2+abs((a-b+1)/2));
应该就这么简单吧!
& 回复于: 13:33:50
& 回复于: 17:09:59
确实长知识啦,谢谢!
& 回复于: 21:34:34
& 回复于: 21:38:17
看来还是要学好数据结构呀!
& 回复于: 19:28:42
高手阿……
不佩服都不行啊
& 回复于: 16:50:25
int&max(int&a,&int&b)
&&&&return((a+b+abs(a-b))/2);
& 回复于: 17:26:50
没有判断,哪儿来的大小?
& 回复于: 17:32:59
& 回复于: 20:25:33
请问怎么删除帖子?&:lol:
& 回复于: 20:59:48
引用:原帖由&"紫云飞扬"&发表:
用printf将两个int数据打印出来。
然后你盯着屏幕很容易找出较大的那个的。
哈哈,这个办法不错...
& 回复于: 16:33:23
用位操作是可行的,如下:
int&&&x,&&y,&
max&=&x&-&((x&-&y)&&&((x&-&y)&&;&;&(sizeof(int)&*&8&-&1));
& 回复于: 16:46:35
to&bibi:&abs也用到了判断吧?
& 回复于: 23:50:51
引用:原帖由&"naiver"&发表:
用位操作是可行的,如下:
int&&&x,&&y,&
max&=&x&-&((x&-&y)&&&((x&-&y)&&;&;&(sizeof(int)&*&8&-&1));
& 回复于: 23:51:52
引用:原帖由&"bibi"&发表:
int&max(int&a,&int&b)
&&&&return((a+b+abs(a-b))/2);
& 回复于: 23:53:03
引用:原帖由&"doublefox"&发表:
max(int&a,&int&b)
&&&&return((a+b)/2+abs((a-b+1)/2));
应该就这么简单吧!
& 回复于: 14:38:48
引用:原帖由&"bibi"&发表:
int&max(int&a,&int&b)
&&&&return((a+b+abs(a-b))/2);
引用:原帖由&"rainshadow"]bibi正解
abs里面怎么实现的?你知道么?
& 回复于: 15:10:58
连小学生都会的问题!
最大数是&两数之和&加&两数之差&然后除以2
(a+b+abs(a-b))/2
& 回复于: 15:13:27
引用:原帖由&"zerozero_nine"&发表:
连小学生都会的问题!
最大数是&两数之和&加&两数之差&然后除以2
(a+b+abs(a-b))/2
最鄙视,不看前面的帖子就乱发表意见的人!
& 回复于: 15:17:00
对不起,&只看到第一页.
改一下可以吧&(a+b+sqrt((a-b)*&(a-b)))/2
& 回复于: 15:27:20
引用:原帖由&"zerozero_nine"&发表:
对不起,&只看到第一页.
改一下可以吧&(a+b+sqrt((a-b)*&(a-b)))/2
真正看完前面的帖子了么?
& 回复于: 17:13:03
精灵王的思路不错啊。呵呵
& 回复于: 17:14:35
在glibc中abs是这样实现的:
int&abs&(int&i)
&&return&i&&&0&?&-i&:&i;
& 回复于: 10:21:32
转换成字符串,而后用strcmp哈哈哈。。
& 回复于: 11:17:00
引用:原帖由&"紫云飞扬"&发表:
用printf将两个int数据打印出来。
然后你盯着屏幕很容易找出较大的那个的。
楼上回答的经典!
& 回复于: 23:45:56
a0110的程序确实写的很是nb,我佩服了1个礼拜啊!
不过,在int类型为16bit长度的时候,源程序出错,以下的改进应该适用于各种编译器了
int&buf[2]={x,y};
z&;&;=(sizeof(int)*8-1);
& 回复于: 13:16:49
:P&小弟看了前面高手的答案。自己也写了个,没有调试过,不知道可不可以
&&&&&&&&&x--;
&&&&&&&&&y--;
&&&&&&&&&while(!y){
&&&&&&&&&&&&&&&&&&&&&&&printf("max&is&x");
&&&&&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&&&&&};
&&&&&&&&&while(!x){
&&&&&&&&&&&&&&&&&&&&&&&printf("max&is&y");
&&&&&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&&&&&}&&&&:em02:
& 回复于: 13:41:21
楼上的兄弟
&&&&while()&
&&&&当()
&&&&就是判断了吧
& 回复于: 16:34:40
& 回复于: 15:16:34
只用逻辑运算完成!
_isA递归函数用到了判断,但在使用中可以循环展开以不用判断语句。
注:以下用到了乘法,但是都是用0或1去乘一个数,这很容易用逻辑运算实现。其实,用逻辑运算可实现c程序用到的一切,处理器芯片内部都是用的逻辑门啊。
#include&&stdio.h&;
#include&&signal.h&;
#define&UNSIGNED_INT&0
#if&UNSIGNED_INT
unsigned&int&_A&=&0xfffffff1;
unsigned&int&_B&=&0xfff1
int&_A&=&0x0f8ffff1;
int&_B&=&0xff2ffff3;
int&A(&int&i&)
&&&&&&&&return&((unsigned&int)_A&&&(1&&&&i))&&;&;&i;
int&B(&int&i&)
&&&&&&&&return&((unsigned&int)_B&&&(1&&&&i))&&;&;&i;
int&bigger_eq(&int&i&)
&&&&&&&&return&A(i)&|&!B(i);
int&bigger(&int&i&)
&&&&&&&&return&A(i)&&&!B(i)&;
int&_isA(&i&)
&&&&&&&&if(&i&&=&0&)
&&&&&&&&&&&&&&&&return&bigger(i)&|&bigger_eq(i);
&&&&&&&&return&bigger(i)&|&(&bigger_eq(i)&&&_isA(i-1)&);
#if&UNSIGNED_INT
unsigned&int&uis()
&&&&&&&&int&s;
&&&&&&&&s&=&_isA(31);
&&&&&&&&return&s*_A&+&(!s)*_B;
&&&&&&&&int&sA,sB;
&&&&&&&&int&s;
&&&&&&&&sA&=&A(31);
&&&&&&&&sB&=&B(31);
&&&&&&&&s&=&_isA(30);
#define&isA&\
&&&&&&&&(&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&\
&&&&&&&&&&&&&&&&((sA^sB)&&&sB)&&&&&&&&&&&&&&&&&\
&&&&&&&&&&&&&&&&|&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&\
&&&&&&&&&&&&&&&&(&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&\
&&&&&&&&&&&&&&&&&&&&&&&&(!(sA^sB))&&&s&&&&&&&&&&&&&\
&&&&&&&&&&&&&&&&)&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&\
&&&&&&&&printf(&"s=%d,sA=%d,sB=%d\n",&s,&sA,&sB&);
&&&&&&&&return&isA*_A&+&(!isA)*_B;
int&main()
&&&&&&&&int&i=0;
&&&&&&&&printf(&"A="&);
&&&&&&&&for(&i=31;&i&;=0;&i--&)
&&&&&&&&&&&&&&&&printf(&"%d",&A(i)&);
&&&&&&&&printf(&"\nB="&);
&&&&&&&&for(&i=31;&i&;=0;&i--&)
&&&&&&&&&&&&&&&&printf(&"%d",&B(i)&);
&&&&&&&&printf(&"\n"&);
#if&UNSIGNED_INT
&&&&&&&&printf(&"&A,B&;=&%u,%u&;\nmax=%u\n",&_A,&_B,&uis()&);
&&&&&&&&printf(&"&A,B&;=&%d,%d&;\nmax=%d\n",&_A,&_B,&is()&);
&&&&return&0;
& 回复于: 15:56:48
cu的牛人真是多!
& 回复于: 10:34:16
#define&SHIFT&(sizeof(int)&*&8&-&1)
int&max(int&x,&int&y)
&&&&&&&&unsigned&int&m,&n,&p;
&&&&&&&&int&ary[2]&=&{x,&y};
&&&&&&&&m&=&x&^&y;
&&&&&&&&n&=&x&&&m;
&&&&&&&&p&=&y&&&m;
&&&&&&&&m&=&(m&&;&;&SHIFT)&&&1;
&&&&&&&&return&ary[(p&&&&!(n&/&p)&)&^&m];
& 回复于: 11:23:29
强悍呐看不太明白
不过(p&&&&!(n&/&p)&)&^&m这句使用了隐含条件判断吧
& 回复于: 11:45:03
那这样呢?
#define&SHIFT&(sizeof(int)&*&8&-&1)
int&max(int&x,&int&y)
&&&&&&&&unsigned&int&m,&n;
&&&&&&&&int&ary[2]&=&{x,&y};
&&&&&&&&m&=&x&^&y;
&&&&&&&&m&=&m&&&~(m&/&2)&&&~(m&/&4);
&&&&&&&&n&=&m&|&0x01;
&&&&&&&&return&ary[&((x&&&n)&+&n&/&2)&/&n&^&!((m&&;&;&SHIFT)&&&0x01)];
& 回复于: 11:52:01
给虾米们讲讲吧
& 回复于: 12:26:43
楼上的能否详细解释一下???
& 回复于: 13:01:05
我解释什么
& 回复于: 13:07:12
原来的程序有个BUG,现在修正了
刚吃完饭,现在又要开会,等会儿再来解释:D
& 回复于: 13:09:56
日程排列的很紧凑嘛
中午是阴阳交替之时
要注意休息阿
& 回复于: 14:18:18
说明一下吧:
这个算法是企图对x、y按位比较,简单地说,如果不考虑+、-号,则在第一次出现两者的位不相同时,该位是1的值比较大,如
左数第8位上,前者是1,后者是0,所以前者比后者大。
对于有符号的情况我们在后面再分析。
1、首先,x^y把x、y中不相同的位置1了,假设x^y=0...01X...X,后面的X表示任意的0或1,这表示在1所在的位置之前的位
x、y是相等的,在这一位上或者x为1、y为0;或者x为0、y为1;我们主要是要确定哪一个为1。可惜的是我们无法得到0...010...0这个数以
及1所在的位号(不然就要用循环去确定,这不符合题目的要求)
2、设m=x^y,则当x&&;&y时,x在该位上为1,所以x&&&&m&=&0...01X...X,所以(x&&
&m)&/&m&大约为1(注意“大约”,因为有等于0的可能存在,我们等会儿把它排除掉);当x&&&y
时,x&&&m&=&0...00X...X,所以(x&&&m)&/&m&=&0,现在我们的程序好象可以工作了。。。
3、但是,有一个BUG,如果m&==&0呢?(x&&&m)&/&m会溢出!m&=&0说明x=y,现在的处理是m&=&m&|&0x01,即把最后一位置1,使m&&;=&1!
这样当m&==&0时,我们不管(x&&&m)&/&m算出来的是个啥结果,反正哪个都一样(x&==&y嘛!),而m&&;&0时,最后一位是不是1不影响我们的计算结果了!
4、前面说过这里还有个BUG,即当x在该位上为1时,我们不能确定(x&&&m)&/&m&一定&=&1,因为尽管x&&&m
在该位上也为1,但x&&&m还是有可能&&&m的(还是感叹如果我们能得到0..010...0这个数就好了!)。现在的处理是
m&=&m&&&~(&m&/&2&)&&&~(&m&/&4),把m这个数变成0...0100X...X,算式也修正为((x&&
&m)&+&m&/&2)&/&m,这个可以满足我们的要求了
5、最后再来考虑一下有符号的情况
设t=((x&&&m)&+&m&/&2)&/&m,f&=&m的第一位=m&&;&;&SHIFT(上面的&0x01其实可以不要)
则当m&=&0时,表示x、y同号,这时按上面的方式确定最大值
当m&=&1时,x、y一正一负,t表示x首位,为1则x&&&0,为0则x&&;=&0
总的说来:
(1)当f=0,t=0时最大值为y&-----1
(2)当f=0,t=1时最大值为x&-----0
(3)当f=1,t=0时最大值为x&-----0
(4)当f=1,t=1时最大值为y&-----1
显然结果是t&^&!f
(如果不让用!那就是t&^&(~f&&&0x01))
& 回复于: 14:24:20
程序才几行,说明倒写了一大堆!呵呵~~~
大家看看有没有什么地方没想到的?
& 回复于: 14:30:26
& 回复于: 15:16:35
m&=&m&&&~(&m&/&2&)&&&~(&m&/&4)
为什么这句可以得到最高的那一位呢
阿我理解了,那并不是最高一位,而是把后头两位给弄成0
可是这样一定能确保(x&&&m)&/&m&=&1吗?
那么(x&m)/m&=&0
& 回复于: 15:30:38
引用:原帖由&"bleem1998"&发表:
m&=&m&&&~(&m&/&2&)&&&~(&m&/&4)
为什么这句可以得到最高的那一位呢
不是最高的一位,而是把m变成:0...0100X...X这样的形式,即1后面有两个0
于是当x在该位上为1时:
(x&&&m)&+&m&/&2&&;=0...0100...0&+&0...0010...0&=&0...0110...0&&;=m
(x&&&m)&+&m&/&2)&&=&0...01001...1&+&0...001001...1&&=&0...011...10&&&2m
所以((x&&&m)&+&m&/&2)&/&m&=&1
而当x在该位上为0时:
(x&&&m)&+&m&/&2&&=&0...00001...1&+&0....001001...1&=&0...0011...1&&&m
所以((x&&&m)&+&m&/&2)&/&m&=&0
& 回复于: 15:44:20
被你打败了
这都想得出来
& 回复于: 19:17:29
引用:原帖由&"yuxh"&发表:
不是最高的一位,而是把m变成:0...0100X...X这样的形式,即1后面有两个0
于是当x在该位上为1时:
(x&&&m)&+&m&/&2&&;=0...0100...0&+&0...0010...0&=&0...0110...0&&;=m
(x&&&m)&+&m&/&2)&&=&0...01001............
也没必要这样,如果能有一个函数返回&m&的第一个为&1&的位置,那么问题不就很简单了?假设&m&的第&i&位是&1,那么
(&(&x&&&(&1&&&&i&)&)&&;&;&i&)&&&x&就代表&x&是否在该位上为&1。
int&bit(&int&v,&int&i&)
return&(&v&&&(1&&&&i)&)&&;&;&i&;
int&first_one(&int&x&)
for(&j=31;&j&;=0;&j--&){
ret&|=&bit(x,j)&&&(!ret);
i&+=&(!ret);
i&=&31&-&i;
& 回复于: 19:19:28
我在前面的解释中说过了不能用循环
for(&j=31;&j&;=0;&j--&)
这里j&;=0不就是判断吗?
& 回复于: 19:28:14
晕了,我上一面的算法里也用了判断,悲哀!
引用:我在前面的解释中说过了不能用循环
for(&j=31;&j&;=0;&j--&)
这里j&;=0不就是判断吗?
这个把循环展开,体力活啊&:roll:
& 回复于: 19:38:30
引用:原帖由&"zleil"&发表:
这个把循环展开,体力活啊&:roll:
想着想着就迷糊了,我也犯过这个错误的呀!幸亏发现得早,不然浪费不少时间了
& 回复于: 19:42:19
引用:原帖由&"yuxh"&发表:
想着想着就迷糊了,我也犯过这个错误的呀!幸亏发现得早,不然浪费不少时间了
说实话,你那个&m&=&a&^&b&真是太强了!!!
& 回复于: 11:16:57
int&&main(int&argc,char&*argv[])
&if(argc!=3)
&&&&&&&&printf("Usage:%s&num1&num2\n",argv[0]);
&&&&&&&&exit(0);
int&num[3];
&&&int&index=0;
&&&num[0]=atoi(argv[1]);
&&&num[1]=atoi(argv[2]);
&&&num[2]=atoi(argv[2]);
&&&index=num[2]-num[0];
&&&index=index/abs(index)+1;
&&&printf("The&max&is&[%d]\n",num[index]);
&&&&&&&&return&1;
& 回复于: 15:08:58
我也写一个新的:
#define&MASK&0x7fffffff
int&max&(int&x,&int&y)
z&=&&(x&;&;31)&-&(y&;&;31)&+&(((x&MASK)&-&(y&MASK))&;&;31);
z=&(z+1)*(z+2)*(3-2*z)/6;
return&z*x&+&(1-z)*y;
& 回复于: 15:31:07
这样子不行吧?
x&&;&0,&y&&;&0的时候z&==&0???
& 回复于: 15:44:02
int&&max(int&&x,int&y)
&&&&int&arr[2];
&&&&arr[0]=x;
&&&&arr[1]=y;
&&&&return&arr[!(x/y)];
& 回复于: 15:53:29
引用:原帖由&"wxycyel"&发表:
请大家有点耐心把前面的帖子看完再发言,也来得及
这之所以是个精彩帖子,是因为前面有好多高人发表了精彩的看法,看一看,对自己是有好处的,同时也不要犯前面n多人犯过的错误
& 回复于: 16:37:59
yuxh&&说得对。我没看清内容,也没想清楚。
& 回复于: 18:14:17
引用:原帖由&"yuxh"&发表:
这样子不行吧?
x&&;&0,&y&&;&0的时候z&==&0???
& 回复于: 19:04:55
新的算法。
#include&&stdio.h&;
#define&INT_SIZE&&sizeof(int)*8
int&max(int&x,int&y)
&&&&&&&&int&arr[8]={x,y,x,x,y,y,x,y};
&&&&&&&&int&z=x-y;
&&&&&&&&int&site=0;
&&&&&&&&int&bitx=!!(x&(1&&(INT_SIZE-1)));
&&&&&&&&int&bity=!!(y&(1&&(INT_SIZE-1)));
&&&&&&&&int&bitz=!!(z&(1&&(INT_SIZE-1)));
&&&&&&&&site^=
&&&&&&&&site^=bity&&1;
&&&&&&&&site^=bitx&&2;
&&&&&&&&return&arr[site];
int&main(int&argc,char&*&argv[])
&&&&&&&&int&x,y;
&&&&&&&&if&(argc&3)&{
&&&&&&&&&&&&&&&&printf&("pleas&input&two&integer!\n");
&&&&&&&&&&&&&&&&return&-1;
&&&&&&&&x=atoi(argv[1]);
&&&&&&&&y=atoi(argv[2]);
&&&&&&&&printf("the&max&is&%d\n",max(x,y));
&&&&&&&&return&0;
& 回复于: 19:13:05
用了需要比较的两个数的和它们差值的最高位。做了一个表。
& 回复于: 19:17:11
用了普通数据和能产生溢出的数据做了测试,在大概有十几组数据。如
这样了数据。都通过了。
& 回复于: 19:38:06
引用:原帖由&"wxycyel"&发表:
&int&max(int&x,int&y)
&&&&&&&int&arr[8]={x,y,x,x,y,y,x,y};
&&&&&&&int&z=x-y;
&&&&&&&int&site=0;
&&&&&&&int&bitx=!!(x&(1&&(INT_SIZE-1)));
&&&&&&&int&bity=!!(y&(1&&(INT_SIZE-1)));
&&&&&&&int&bitz=!!(z&(1&&(INT_SIZE-1)));
&&&&&&&site^=
&&&&&&&site^=bity&&1;
&&&&&&&site^=bitx&&2;
&&&&&&&return&arr[site];
具体没看完,
问一下:int&z=x-y;语句,你考虑溢出了吗?
还有,建议大家贴出程序之前,把自己的思路做一个简要的描述!
& 回复于: 19:39:55
引用:原帖由&"wxycyel"&发表:
用了普通数据和能产生溢出的数据做了测试,在大概有十几组数据。如
这样了数据。都通过了。
这不足以证明你的程序的正确性,你必须进行证明!
& 回复于: 19:41:30
引用:原帖由&"win_hate"&发表:
#define&MASK&0x7fffffff
int&max&(int&x,&int&y)
&&&z&=&&(x&;&;31)&-&(y&;&;31)&+&(((x&MASK)&-&(y&MASK))&;&;31);
&&&z=&(z+1)*(z+2)*(3-2*z)/6;
&&&return&z*x&+&(1-z)*y;
做一个简要的解释吧,一起分享
& 回复于: 19:50:15
引用:原帖由&"win_hate"&发表:
#define&MASK&0x7fffffff&
int&max&(int&x,&int&y)&
&&&int&z;&
&&&z&=&&(x&;&;31)&-&(y&;&;31)&+&(((x&MASK)&-&(y&MASK))&;&;31);&
&&&z=&(z+1)*(z+2)*(3-2*z)/6;&
&&&return&z*x&+&(1-z)*y;&
当x&;0,y&;0时,x&;&;31=0,y&;&;31=0,x&MASK&=0,y&MASK=0,所以第一个z=0
第二个z&=&1*2*3/6&=&1
可以用2、3试一下的说
sorry!我还没看懂算法。。。
& 回复于: 20:02:30
真受不了,没事瞎折腾。
& 回复于: 20:40:45
wxycyel是个高手,他的程序还是基于x-y的,把x-y、x、y三个的最高位组合在一起进行判断,所以用了一个2^3=8的数组以确定最后的值
& 回复于: 20:41:26
我对C不熟,我想应该可以这样。
假设:我们无法判断(在vi编辑器中&)两个武士谁最强。
&&&&&&让这两个武士进入黑屋子(相当于系统内部机制)命令他们杀死对方才能出来。我们不用判断,只要看谁出来就知道了。
eg:&&&&int&a.b;
&&&&&&&&&&...a-b&.......;&printf("The&max=a\n");
&&&&&&&&&&&...b-a.......;&printf("The&max=b\n");
设法让系统自动判断(黑屋子)并结束其中一个语句,让它执行不到printf(在黑屋子中死掉)。
而另一个可以(走出黑屋子)。
& 回复于: 20:49:29
引用:原帖由&"yuxh"&发表:
当x&;0,y&;0时,x&;&;31=0,y&;&;31=0,x&MASK&=0,y&MASK=0,所以第一个z=0
第二个z&=&1*2*3/6&=&1
可以用2、3试一下的说
sorry!我还没看懂算法。。。
x&MASK&=0,y&MASK=0,你弄糊涂了吧
他这个算法不错,用((x&mask)&-&(y&mask))&&;&;&31来决定同符号的两数的大小比较,然后再加上x,y的符号信息,就能完全判断了。其他的代码我还没弄懂,望作者加以解释。
这个算法应该算是以上算法中[color=blue]最简单[/color]的了!
& 回复于: 20:54:23
引用:原帖由&"zleil"]牧耍�
sorry!我没看清()!
& 回复于: 20:56:55
引用:原帖由&"zleil"&发表:
具体没看完,
问一下:int&z=x-y;语句,你考虑溢出了吗?
还有,建议大家贴出程序之前,把自己的思路做一个简要的描述!
& 回复于: 21:06:35
根据win_hate的想法,再来一段
#define&MASK&0x7fffffff
int&max&(int&x,&int&y)
&&&&int&&&&&//&x的符号
&&&&int&&&&&//&y的符号
&&&&int&s;&&&&&&//&x,y在去掉符号位后,如果x大,则s=1;否则为0
&&&&int&is_x;&&//&如果最大值是x,则为1,否则为0&
&&&&sx&=&x&&;&;&31;
&&&&sy&=&y&&;&;&31;
&&&&s&=&((x&MASK)&-&(x&MASK))&&;&;&31;
&&&&is_x&=&(&(!(sx^sy))&&&s&)&|&(&(sx^sy)&&&sy&);
&&&&return&is_x*x&+&(!is_x)*y;
sx&&sy&&s&&&&&is_x
0&&&1&&&&*&&&&&&1
0&&&0&&&&s&&&&&&s
1&&&1&&&&s&&&&&&s
1&&&0&&&&*&&&&&&0
& 回复于: 21:10:13
不好意思,不会引用。
我考虑了溢出的情况。这个算法的主要思路是根据需要比较的两个整数的符号(x,y的最高位)和它们之间的差值的正负(z的最高位)来做比较的,在预先定义的表(arr[8],相当于一张状态图)中查找相应值。
& 回复于: 21:12:02
zleil的算法应该是和我一个思路。
& 回复于: 21:17:35
引用:原帖由&"wxycyel"]zleil的算法应该是和我一个思路。
哈哈,我是偷的你的思路啊。
先确定去符号后的大小比较,这个思路太好了!!!
& 回复于: 21:21:24
我也是在大家先前发的贴子的启发下才想到这个方法的。
& 回复于: 21:27:34
引用:原帖由&"wxycyel"]我也是在大家先前发的贴子的启发下才想到这个方法的。
所以说看一下别人的东西还是有好处的吧?^_^
不然不会这么无聊的一个贴子顶到现在!
& 回复于: 22:24:04
这段代码的简单说明:
#define&MASK&0x7fffffff
int&max&(int&x,&int&y)
&&z&=&&(x&;&;31)&-&(y&;&;31)&+&(((x&MASK)&-&(y&MASK))&;&;31);
&&z=&(z+1)*(z+2)*(3-2*z)/6;
&&return&z*x&+&(1-z)*y;
思路:计算&x-y&的差,自己处理进位:
(((x&MASK)&-&(y&MASK))&;&;31)&计算低&31&位相减后的符号,0&或&-1。也可以看成低&31&位相减后对高位的&&借位。
(x&;&;31)&-&(y&;&;31)&是第&32&位的差,带符号扩展
z&=&&(x&;&;31)&-&(y&;&;31)&+&(((x&MASK)&-&(y&MASK))&;&;31);
可以分析出,z&有四种可能的值,1,&0,&-1,&-2。其中&
1,&0&对应&x&;=y,&-1,&-2&对应&x&&&y
我对&z&作一个修正,即一个映射,把&1,&0&对应为&1;&-1,&-2&对应为&0。映射可用&Lagrange&插值公式得到。
还是&Lagrange&插值,&1&-&;&x,&0&-&;&y
ps&;&第二行也可以直接从最高位判断正负。
& 回复于: 22:26:06
yuxh&的算法很精彩,技巧性很强。我看了半天才明白(在注释的帮助下)。
& 回复于: 18:03:43
http://community.csdn.net/Expert/topic/.xml?temp=.7769739
大家可附带解决一下这个问题,CU讨论的比CSDN深多了。
还是CU牛人多!
& 回复于: 18:22:02
#include&&set&;
using&namespace&
#include&&iostream&;
int&main(){
&&&&int&s[2]={5&,&3&};
&&&&set&int&;&_set(s&,s+2);
&&&&set&int&;::iterator&
&&&&it=_set.begin();
&&&&cout&&(int)(*(++it))&&
& 回复于: 09:45:05
这是茴香豆的茴字的第5中写法,哈哈。
& 回复于: 11:56:38
根据:&大数&-&&小数&必定等于&正数&,&小数&-&大数&必定等于&负数
而负数,在机器里用补码表示,第&31位是1
int&max(int&a&,&int&b)&{
&&&&&int&tmp[2];
&&&&&tmp[(a-b)&;&;31]&=&a;
&&&&&tmp[(b-a)&;&;31]&=&b;
&&&&&return&tmp[0];
:)&我没有实验过,各位验证一下,看对不对....
& 回复于: 13:40:44
不对。没考虑溢出。
& 回复于: 21:32:30
引用:原帖由&"FH"]不对。没考虑溢出。
FH&所言甚差.....
我认为,我写的函数:
int&max(int&a,&int&b)&{
&&&&&&int&tmp[2];
&&&&&tmp[(a-b)&;&;31]&=&a;
&&&&&tmp[(b-a)&;&;31]&=&b;
&&&&&return&tmp[0];
能够非常高效,准确地完成任务,并没有什么所谓的溢出问题。
1、大家都知道:
&&&&singed&int&取值范围是&-0x7fffffff&----&+0x7fffffff
&&&&&&unsinged&int&取值范围是:&0&---&0xfffffff
&&&&&这是32位机器&int&类型所能提供的最大取值范围(当然你可以用long&long&而达到64位)。
&&&我们作个实验:
&&&&&printf("a=%d,b=%d\t",&0x7fffffff,&0x7ffffff0);
&&&&&printf("the&max&is&%d\n",&max(0x7fffffff,&0x7ffffff0));
看看结果:
a=,&b=&&&&&&&&&the&max&is&
结果完全正确,并没什么溢出问题。
2、按&FH&的逻辑,看看下面代码是否有问题?
int&sum(int&a,&int&b)&{
&&&&&&return&a&+&b;
错误!!!!没有考虑溢出问题!!!!!
那么所有涉及运算的代码都必须考虑溢出问题!!!!
3、结论是:当我们作运算时,只要在&数据类型的取值范围内作正确的运算,就没必要过多考虑溢出问题。。。。
& 回复于: 21:37:56
引用:1、大家都知道:&
&&&singed&int&取值范围是&-0x7fffffff&----&+0x7fffffff&
这就是个错误.
#include&&stdio.h&;
int&main()
&&&&printf("%d\n",-0x7fffffff);
&&&&printf("%d\n",0x);
&&&&return&0;
[root@Reinnat&tmp]#&./055
你竟然认为-&是最小的.~~&兄弟&治学要严谨
& 回复于: 21:44:31
溢出不溢出自己看吧.
#include&&stdio.h&;
int&max(int&a,&int&b)&{
&&&&int&tmp[2];
&&&&tmp[(a-b)&;&;31]&=&a;
&&&&tmp[(b-a)&;&;31]&=&b;
&&&&return&tmp[0];
int&main()
&&&&printf("0x:%d\n",0x);
&&&&printf("0x7fffffff:%d\n",0x7fffffff);
&&&&printf("%d\n",max(0xx7fffffff));
&&&&return&0;
[root@Reinnat&tmp]#&./056
0x7fffffff:
负数大于正数了.~&哎.~~引用:能够非常高效,准确地完成任务,并没有什么所谓的溢出问题。&
& 回复于: 21:47:01
可不可以用strcmp()函数?
虽然它是用来比较两个字符串的,但是,char和int是可以互用的
先定义一个字符串,再用getchar()输入,是不是就可以?
或者使用强制类型转换!
这写只是我的一点想法,没有试,不知道行不行!
& 回复于: 21:52:48
引用:原帖由&"mq110"&发表:
你竟然认为-&是最小的.~~&兄弟&治学要严谨
嗯~~~&你说得对,我没有考虑到。。。
事实胜如雄辩
& 回复于: 21:53:59
不过你的代码确实不错&如果考虑到了这个溢出的话&将是不错的.~
看出来你有深厚的汇编功底.
& 回复于: 11:26:51
引用:原帖由&"mik"&发表:
FH&所言甚差.....&
嘿嘿,呵呵,哈哈,活活,哼哼……
& 回复于: 13:20:33
这让我想到了孔乙己
& 回复于: 19:24:49
这个问题实际上求有符号运算的溢出位。
工作很久了,今天借这个机会参与讨论,有机会复习一下
&公式:[x+y]补=[x]补+[y]补&
&&& [x-y]补=[x]补+[-y]补&
&&例题略。&
&&溢出:运算结果超过允许取值范围→溢出→结果出错。&
&&变形码判溢出(双符号位)
&&&正号——用00表示;负号——用11表示。&
&&&运算结果符号是00或11→无溢出。&
&&&运算结果符号是01→正溢出&
&&&运算结果符号是10→负溢出&
至于如何做到双符号位,各位开动脑筋吧。
前面诸位的方案都有问题
mq110&的也有问题,&大家别把他的当成正确答案了!要接着讨论下去。
& 回复于: 19:27:09
&;&;mq110&的也有问题
倒.~&我就是说说别人的问题.&我有啥问题啦?
& 回复于: 19:30:57
每天&在CU的&C版&玩的可开心了&看着大家发着各种搞笑的帖子.(我也总发那样的帖子.)
& 回复于: 19:52:22
:roll:&谈了那么久&&好象挺好玩啊&&&:em17:
& 回复于: 11:52:18
a&;b?a:b就可以了
& 回复于: 11:56:08
引用:原帖由&"fog_java"&发表:
a&;b?a:b就可以了
& 回复于: 15:53:04
引用:原帖由&"wwwxdmfive"&发表:
&&例题略。&
&&溢出:运算结果超过允许取值范围→溢出→结果出错。&
&&变形码判溢出(双符号位)
&&&正号——用00表示;负号——用11表示。&
&&&运算结果符号是00或11→无溢出。&
&&&运算结果符号是01→正溢出&..........
要真的确定一下溢出还不如用内嵌汇编:
读一下标志寄存器的OF位,就可知有无溢出。
& 回复于: 17:17:42
如果是面试,
&&就是两个数吗,那用眼睛看就可以了&:em02:
& 回复于: 21:15:33
溢出是一个很广泛的问题.
推广开来,&其实,几乎每个人编程都会犯溢出的问题.
你会认为以下最简单函数就没溢出问题吗?&而又有谁去想到它的溢出问题?
int&sum(int&a,&int&b)&{
&&&&&return&a+b;
& 回复于: 21:27:55
其实就像&这个问题本身.
实际我们不需要考虑&用这么多方法来求两个数的大值.
而你不是也去求了?
& 回复于: 20:23:26
把两个数相减,然后printf.比上楼强点吧:)
& 回复于: 09:30:56
这帖越来越没“技术含量”。
& 回复于: 11:03:02
前面有个兄弟给出了很经典的算法,为什么没人注意到?
13+5=18/2=9&
4+(-13)=-9&
-5+13=8/2&
10+4=14/2&
7+11=18/2&
11+7=18/2&
-16-2=-18/2&
16+2=18/2&
z=x+y+(-1*(x-y))&
好久没接触程序了,代码都忘得差不多了,不过算法永远都不会忘的,数学的魅力是如此吸引人!!
& 回复于: 11:06:29
引用:原帖由&"FH"]这帖越来越没“技术含量”。
这帖越来越没“技术含量”!
& 回复于: 11:10:11
原文链接:
转载请注明作者名及原文出处
Copyright &
ChinaUnix.net
&&All Rights Reserved
感谢所有关心和支持过ChinaUnix的朋友们
京ICP证041476号
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。}

我要回帖

更多关于 算法导论 23.1 11 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信