免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
123
最近访问板块 发新帖
楼主: sh365
打印 上一主题 下一主题

[C] NO1贴:在两个数中找较大的那一个 [复制链接]

论坛徽章:
0
21 [报告]
发表于 2011-10-29 20:52 |只看该作者
回复 19# AD8018


    不用函数怎么做?

论坛徽章:
0
22 [报告]
发表于 2011-10-29 20:54 |只看该作者
回复 21# caijicheng2006


    想了半天,除了4楼、16楼的减法,还是没想到其他招。

论坛徽章:
0
23 [报告]
发表于 2011-10-29 21:21 |只看该作者
回复 22# AD8018

其实还可以加法阿, 加上b的负值

论坛徽章:
0
24 [报告]
发表于 2011-11-01 09:11 |只看该作者
abs里面肯定用了 if,  : ? , >, >=, <, <=吧~

论坛徽章:
9
摩羯座
日期:2013-08-15 15:18:48狮子座
日期:2013-09-12 18:07:47金牛座
日期:2013-09-16 13:23:09辰龙
日期:2013-10-09 09:03:27白羊座
日期:2013-10-17 13:32:44子鼠
日期:2014-04-23 15:09:38戌狗
日期:2014-09-17 11:37:542015年亚洲杯之韩国
日期:2015-03-26 10:16:442015亚冠之武里南联
日期:2015-08-18 14:55:52
25 [报告]
发表于 2011-11-01 14:44 |只看该作者
回复  OwnWaterloo


    要是a-b溢出呢?
pmerofc 发表于 2011-10-28 20:48



OwnWaterloo确实厉害,不过这个问题我怎么有既视感?
在OwnWaterloo思路基础上,解决溢出的方法:
  1. #include <stdio.h>
  2. #include <stdlib.h>

  3. int _max(int a, int b)
  4. {
  5.         const int v[2] = {a, b};
  6.         const int s = (((unsigned)(a ^ b)) >> 31);
  7.         return v[(!s) * (((unsigned)(a - b)) >> 31) + s * (((unsigned)a) >> 31)];
  8. }

  9. int main(void)
  10. {
  11.         int a=0, b=0;
  12.         while (scanf("%d%d", &a, &b)==2)
  13.                 printf("%d\n", _max(a,b));
  14.         return 0;
  15. }
复制代码

论坛徽章:
2
青铜圣斗士
日期:2015-11-26 06:15:59数据库技术版块每日发帖之星
日期:2016-07-24 06:20:00
26 [报告]
发表于 2011-11-01 20:10 |只看该作者
这个方法是我想出来的
让ls几位误会了……
不记得是在哪里看过一段代码(估计也是笔试题?):

  1. int max(int a, int b) { return (&a)[(a-b)>>31]; }
复制代码
但可以吐槽的地方很多……
1. 调用约定
其实这个倒容易,直接复制到数组里,就与调用约定无关了。
让AD8018花时间测试其他用寄存器传递参数的平台是我的错……

2. 31
不仅仅是sizeof(int)与CHAR_BIT的问题。
(sizeof(int)*CHAR_BIT-1) 也不一定对。
只有unsigned char保证没有padding bit。 貌似C99某个TC也保证char/signed char没有padding bit。
其他的整数类型, 比如 int, 1^(sizeof(int)*CHAR_BIT)-1 <= UINT_MAX 。

3. 有符号数表示法
C99才新增加了有符号数表示法只能在三种当中取。
三种表示法也都恰好有一个sign bit。
但sign bit的位置C99并没有说明。

4. >>
即使是补码表示,31value, 1sign(且最高),0padding, 有符号数负值右移也是实现定义的。

5. 溢出
这个我当时倒是没考虑到……


也不是说题目就完全无意义。 只要将一些假设说清楚, 这样的题目可以训练对数的表示的认识。
但很多出题的仅仅将自己心中的"标准"答案在自己的平台上编译运行了,就认为此答案是四海皆准了,将假设当作隐含/默认条件 —— 让人很难办啊

论坛徽章:
2
青铜圣斗士
日期:2015-11-26 06:15:59数据库技术版块每日发帖之星
日期:2016-07-24 06:20:00
27 [报告]
发表于 2011-11-01 20:16 |只看该作者
回复 25# w_anthony

const int s = (((unsigned)(a ^ b)) >> 31);
同号0,异号1?

(!s)*x +  s*y 就类似 s? y: x ?

同号,(((unsigned)(a - b)) >> 31),就按结果的符号位;
异号,(((unsigned)a) >> 31) (一正一负)就 a<0? b: a?

论坛徽章:
2
青铜圣斗士
日期:2015-11-26 06:15:59数据库技术版块每日发帖之星
日期:2016-07-24 06:20:00
28 [报告]
发表于 2011-11-01 20:18 |只看该作者
回复 24# rollingpig

不一定……  i386:

  1.         movl        4(%esp), %eax
  2.         cltd
  3.         xorl        %edx, %eax
  4.         subl        %edx, %eax
  5.         ret
复制代码
应该是为了避免分支……

论坛徽章:
2
程序设计版块每日发帖之星
日期:2015-06-17 22:20:00每日论坛发贴之星
日期:2015-06-17 22:20:00
29 [报告]
发表于 2011-11-01 21:14 |只看该作者
提示: 作者被禁止或删除 内容自动屏蔽
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP