`
tangyuan1314
  • 浏览: 38978 次
  • 性别: Icon_minigender_2
  • 来自: 南京
社区版块
存档分类
最新评论

比较两个数a、b的大小,不能使用大于/小于、if、switch,?:等判断语句

阅读更多

今天面试碰到了这个问题,知道是位操作,不过当时没想起来,回来查了查总结一下。其实方法很简单,就是相减后看符号位,将减的结果的符号位移位到末尾,再和1与操作,或者直接和0x80000000与,得出的符号位再右移至末尾,作为数组的下标。int型占4字节,即32位,在-1为补码的机器上,1代表负数,0代表正数

int max(int x,int y)

{

int buf[2]={x,y};

unsigned int z;

        z=x-y;

        z=z>>31;//符号位移至末尾,作为数组下标

return buf[z];

}

上述代码是从网上查的,这是基础版本,但是未考虑内存溢出,如127-(-128)得出的结果超出了8位所能表示的数。并且上述版本不可直接用java写,java中没有无符号类型,因为java中右移运算补位是根据符号位,符号位为1就补1,符号位为0就补0,因此右移后可和1与操作。

下面的版本是考虑溢出,即判断两个数的符号相同否,相同的话就不会产生溢出。不相同的话,直接看符号位就ok了。下面上代码。

 

int max1(int x,int y){//符号相同,返回x,y中的大值
  unsigned int z;
  z=((x-y)>>31)&1;

  return (1-z)*x+z*y;//这种写法很巧妙
}

int max2(int x,int y){//符号不同,直接判断x的正负即可,返回最大值
  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);
}

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

   其实上述的巧妙部分是基于插值,有人给出了精简的程序,思想同上。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);

}
 

 总结一下:

1、基本思想:位操作,找符号位

 

a^b 的最高位 ---- 判断符号是否相同

a-b 的最高位 ---- 在符号相同的情况下判断大

a   的最高位 ---- a的符号

b   的最高位 ---- b的符号

2、得出大(小)的数

   把大小关系对应到一个数组当中

 

    使用插值

 

分享到:
评论

相关推荐

    C语言程序设计标准教程

    应该把变量的值和变量的地址这两个不同的概念区别开来。变量的地址是C编译系统分配的,用户不必关心具体的地址是多少。 变量的地址和变量值的关系如下: &a--->a567 a为变量名,567是变量的值,&a是变量a的地址。在...

    freemarker总结

    [ {“Akey”:”Avalue”},{“Akey1”:”Avalue1”}, {“Bkey”:”Bvalue”},{“Bkey1”:”Bvalue1”}, ] hashes {“you”:”a”,”me”:”b”,”he”:”c”} 注释标志 这里是注释 --> 旧版本的freemarker采用...

    你必须知道的495个C语言问题

    3.15 我要检查一个数是不是在另外两个数之间,为什么if(abc)不行? 3.16 为什么如下的代码不对?inta=1000,b=1000;longintc=a*b; 3.17 为什么下面的代码总是给出0?doubledegC,degF;degC=5.0/9*(degF-32); ...

    c#入门之分支语句使用方法(三元运算符、if语句、switch语句)

    中,返回的两个表达式之间,使用 : 号隔开,而不是 , 号,注意了: 代码如下:string h = (k<10) ? “k小于10″:”k大于或等于10”; 当然,这种表达式适合简单的比较后返回值处理,但对于根据比较结果而执行大量...

    javascript入门笔记

    2、如果 a 大于 b的话 ,则交换两个数字的位置 使用 短路&&,扩展赋值运算符,位运算 4、条件运算符(三目运算) 单目(一元)运算符 :++,--,! 双目(二元)运算符 :+,-,*,/,%,>,<, ... ... 三目(三元)运算符 ...

    《你必须知道的495个C语言问题》

    3.15 我要检查一个数是不是在另外两个数之间,为什么if(a b c)不行? 40 3.16 为什么如下的代码不对?int a=1000, b=1000; long int c=a * b; 40 3.17 为什么下面的代码总是给出0?double degC, degF; degC= ...

    PHP基础教程 是一个比较有价值的PHP新手教程!

    // 一个包含两个元素的数组 $a[0] = "first"; $a[1] = "second"; $a[] = "third"; // 添加数组元素的简单方法 // 现在$a[2]被赋值为"third" echo count($a); // 打印出3,因为该是...

    计算机程序设计(C语言)教案.doc

    " " " "else if (表达式n) 语句n " " " "else 语句n+1 " " "if语句 "在if语句的内部使用if语句,例如: "if语句的嵌 " "的嵌套 "if ( )if ( ) 语句1else if ( ) 语句2else 语句3 "套,注意与i" " " "f语句的三种" ...

    C语言常见错误小结,希望对大家有帮助

    字符“a”送给c1,字符“ ”送给c2,字符“b”送给c3,因为%c只要求读入一个字符,后面不需要用空格作为两个字符的间隔。 10.输入输出的数据类型与所用格式说明符不一致。 例如,a已定义为整型,b定义为实型 a=3;b=...

    整理后java开发全套达内学习笔记(含练习)

    注意:两个 byte 数相加,变 int 型) short 16bit, -2^15~2^15-1 (2^15=32768) int 32bit, -2^31~2^31-1 (2147483648,20亿,10位有效数字) long 64bit, -2^63~2^63-1 (900亿亿,20位有效数字) float 32bit, 9...

    Screenshot_2019-11-15-13-34-57-96_860bc48c3aad114ac1ee206f23d5a6f5.png

    然后从前往后依次与case子句中所列出的各个常量表达式的值进行比较,若表达式的值与常量中的值相等,就开始进入相应的case后面的语句组执行,遇到后续的case也不再进行判断,直至遇到break语句或switch语句结束 ...

    【03-流程控制与数组】

    •for 循环圆括号中只有两个分号是必须的,初始化语句、循环条件、迭代语句部分都可以省略,如果省略了循环  条件,则这个循环条件默认是true,将会产生一个死循环。 •使用for循环时,还可以把初始化条件定义...

    华为编程开发规范与案例

    对某交换类进行计费测试,字冠011对应1号路由、1号子路由,有4个中继群11,12,13,14(都属于1#模块),前后两个群分别构成自环。其中11,13群向为出中继,12,14群向为入中继,对这四个群分别进行计费设置,对出入中继都...

Global site tag (gtag.js) - Google Analytics