叶子的小屋
求较小的值,不能用 比较运算符 if-else ?: while for 内嵌汇编 递归 第三方函数(转)
2013-12-1 admin


求较小的值,不能用 比较运算符 if-else ?: while for 内嵌汇编 递归 第三方函数

int Min(int a, int b)

{

//write code here

}



原网址:http://topic.csdn.net/u/20110816/19/3194c61c-fc4d-41ad-8357-9110d8cdc6b0.html



 



 



 



下面是我的解答,以及我搜集的解答,以及我的解答



需要声明的是没有考虑溢出的情况,对于a-b溢出的问题,建议都转成64位的,



 



#include <cstdio>

#include <assert.h>



int Min(int x, int y)

{

int tmp = (x - y) * (((x - y) >> (sizeof(int) * 8 - 1)) | 1);

return ((x + y) - tmp) / 2;

}



int Min2(int x, int y)

{

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

int sign = ((x - y) >> (sizeof(int) * 8 - 1)) & 1;

return min[sign];

}



int Min3(int a, int b)

{

int sum = a + b;

b = a - b;

a += b * (b >> (sizeof(int) * 8 - 1));

return sum - a;

}



int Min4(int a, int b)

{

int sign = ((unsigned int)(a - b)) >>31;

return a * sign + b * (1 - sign);

}



int Min5(int a, int b)

{

return (&b)[(a-b)>>31];

}



int main()

{

int x, y;



//   assert(Min3(0x80000000, 0x7fffffff) == 0x80000000);

while(scanf("%d%d", &x, &y) != EOF)

{

printf("the minimal is %d\n", Min5(x, y));

}

return 0;

}

还有大家是怎么编排代码的啊,给我推荐个插件



 



有必要对Min5 介绍下,来自CSND



int min(int a, int b)

{

return (&b)[a-b>>31];

}

在windows系统上完美

&b获得b在堆栈上的指针,a-b>>31的结果只能是-1或者0

当a大于b时 (a-b>>31) = 0, 此时函数返回(&b)[0] = b,

当a小于b时 (a-b>>31) = -1, 此时函数返回(&b)[-1]=a,

为什么(&b)[-1]会是a?

函数在调用前会将参数压入堆栈,

int m = min(55,33);

00E6142E push 21h -> b = 33

00E61430 push 37h -> a = 55

00E61432 call min (0E610F5h)

在调用min函数的时候,参数按从右向左的顺序压入堆栈,

堆栈是段连续内存,在windows下堆栈地址是从高到低,

也就是先push进入的参数会占用高内存地址,

b先被push,所以b占用高内存地址,

a被后push,a占用紧连着b的低内存地址,

+ &b 0x0030fd80 int *

+ &a 0x0030fd7c int *

神奇的是,我们知道 (&b)[0]返回的是b本身的值,

而(&b)[-1]返回的却是a 的值,也就是说(&b)[-1]返回了上四个字节的值,

(&b)[-1] = *(&b - 1) = a;(这里b是int型,所以-1相当于将地址向后偏移4个字节)



 



原文:http://www.cppblog.com/Cunch/archive/2011/08/20/153983.html