免费注册 查看新帖 |

Chinaunix

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

为何 #define ISUNSIGNED(a) (a>=0 && ~a>=0) 有问题(判断是否有符号) [复制链接]

论坛徽章:
2
程序设计版块每日发帖之星
日期:2015-06-17 22:20:00每日论坛发贴之星
日期:2015-06-17 22:20:00
21 [报告]
发表于 2010-06-13 23:49 |只看该作者
提示: 作者被禁止或删除 内容自动屏蔽

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
22 [报告]
发表于 2010-06-13 23:54 |只看该作者
都是宽于律己,何不自己先用标准解答呢?

论坛徽章:
0
23 [报告]
发表于 2010-06-14 02:53 |只看该作者

  1. #include <stdio.h>

  2. int main()
  3. {
  4. #define ISSN(x) ( x-x-1<0 ? 1:0 )
  5.         int i;
  6.         unsigned int j;
  7.         for( i=0; (unsigned int) i != 0xffffffff; (unsigned int) i++ )
  8.         {
  9.                 if(! ISSN(i) )
  10.                 {
  11.                 puts("i error\n");
  12.                 return -1;
  13.                 }
  14.         }
  15.         for( j=0; j != 0xffffffff; j++ )
  16.         {
  17.                 if( ISSN(j) )
  18.                 {
  19.                         puts("j error\n");
  20.                         return -1;
  21.                 }
  22.         }
  23.         puts("All ok!\n");
  24.         return 0;
  25. }
  26. /*
  27. $ time ./issn
  28. All ok!

  29. real    0m26.004s
  30. user    0m25.972s
  31. sys     0m0.014s
  32. $
  33. */
复制代码

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
24 [报告]
发表于 2010-06-14 08:01 |只看该作者
楼上错的, 换成 signed/unsigned char 试试

论坛徽章:
2
程序设计版块每日发帖之星
日期:2015-06-17 22:20:00每日论坛发贴之星
日期:2015-06-17 22:20:00
25 [报告]
发表于 2010-06-14 08:14 |只看该作者
提示: 作者被禁止或删除 内容自动屏蔽

论坛徽章:
1
数据库技术版块每日发帖之星
日期:2016-05-27 06:20:00
26 [报告]
发表于 2010-06-14 11:05 |只看该作者
笨死了, 居然试验了半天

#define ISUNSIGNED(t) \
((t) > 0 && (sizeof(t) != sizeof(~(t)) || (~t) >  ...
群雄逐鹿中原 发表于 2010-06-13 23:41



   
这个有点问题吧


    unsigned t = 0;
   按上式判断就是假了。

论坛徽章:
1
数据库技术版块每日发帖之星
日期:2016-05-27 06:20:00
27 [报告]
发表于 2010-06-14 11:07 |只看该作者
求个反例,为何
#define ISUNSIGNED(a) (a>=0 && ~a>=0) 在 ansi c里不行,我用gcc试了好多例子了,都可以正常判断出来是unsigned的还是signed的。。。。。,gcc的版本也比较新。

论坛徽章:
0
28 [报告]
发表于 2010-06-14 12:41 |只看该作者
。。。。。。。保持形象。

论坛徽章:
324
射手座
日期:2013-08-23 12:04:38射手座
日期:2013-08-23 16:18:12未羊
日期:2013-08-30 14:33:15水瓶座
日期:2013-09-02 16:44:31摩羯座
日期:2013-09-25 09:33:52双子座
日期:2013-09-26 12:21:10金牛座
日期:2013-10-14 09:08:49申猴
日期:2013-10-16 13:09:43子鼠
日期:2013-10-17 23:23:19射手座
日期:2013-10-18 13:00:27金牛座
日期:2013-10-18 15:47:57午马
日期:2013-10-18 21:43:38
29 [报告]
发表于 2010-06-14 13:24 |只看该作者
这里似乎分成 理论派 和 实践派 了

论坛徽章:
0
30 [报告]
发表于 2010-06-14 13:38 |只看该作者
本帖最后由 churchmice 于 2010-06-14 13:58 编辑

回复 1# glq2000
char和short都有Integer promotion,都会被promote成int,所以是无法判断unsigned short,unsigned char的符号性的,看下面的代码就明白了

Integer types smaller than int are promoted when an operation is performed on them. If all values of the original type can be represented as an int, the value of the smaller type is converted to an int; otherwise, it is converted to an unsigned int. Integer promotions are applied as part of the usual arithmetic conversions to certain argument expressions; operands of the unary +, -, and ~ operators, and operands of the shift operators.

  1. #include <stdio.h>
  2. #define ISUNSIGNED(x) ( x>=0 && ~x >=0 )
  3. int main(void){
  4.                 signed char a =1;
  5.                 unsigned char b  =1;
  6.                 signed int c = 1;
  7.                 unsigned int d =1;
  8.                 signed short e =1;
  9.                 unsigned short f=1;
  10.                 signed long g =1;
  11.                 unsigned long h =1;
  12.                 if ( ISUNSIGNED(a) ){
  13.                                 printf("a is unsigned\n");
  14.                 }
  15.                 if ( ISUNSIGNED(b) ){
  16.                                 printf("b is unsigned\n");
  17.                 }
  18.                 if ( ISUNSIGNED(c) ){
  19.                                 printf("c is unsigned\n");
  20.                 }
  21.                 if ( ISUNSIGNED(d) ){
  22.                                 printf("d is unsigned\n");
  23.                 }
  24.                 if ( ISUNSIGNED(e) ){
  25.                                 printf("e is unsigned\n");
  26.                 }
  27.                 if ( ISUNSIGNED(f) ){
  28.                                 printf("f is unsigned\n");
  29.                 }
  30.                 if ( ISUNSIGNED(g) ){
  31.                                 printf("g is unsigned\n");
  32.                 }
  33.                 if ( ISUNSIGNED(h) ){
  34.                                 printf("h is unsigned\n");
  35.                 }
  36.                 return 0;
  37. }
复制代码
编译的时候有提示
sign.c:15: warning: comparison is always true due to limited range of data type
sign.c:27: warning: comparison is always true due to limited range of data type

运行的结果
xxx:~> ./sign
d is unsigned
h is unsigned


可见short和char类型是无法判断出来的
汇编代码里面也可以看到有两句
movzbl movsbl
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP