abs函数的实现

abs函数即取一个整形数的绝对值,今天在IDA查看cygwin的实现时候发现其实现过程,这里总结三种情况(感觉这类型东西也很适合用于笔试或面试):

 

(1)带if分支的利用补码特性:

正数的补码和原码相同;负数的补码是:补码=~(其正数的)原码+1。因此如果是负数求绝对值可以:(绝对值)原码=~(补码-1)

int _abs(signed int i)
{
    if (i<0)
        return ~(--i);
    return i;
}

(2)带if分支(判断分支)的传统想法:

这就很接近一般人想法了,正数保持原样,负数取反

int _abs(singed int p)
{
    return p>0?p:-p;
}

(3)不带if分支(判断分支)的位运算:

我是从cygwin中逆向得到的代码

int __cdecl _abs(signed int i)
{
    return ((i >> 31) ^ i) - (i >> 31);
}

负数肯定第一位是1,右移31位后是0xFFFFFFFF,-1与原值异或即是求反,减去-1即是加一:~补码 - (-1)=(其正数的)原码

正数则第一位是1,右移31位后是0x00000000,0与原值异或即是保持原值,正数还是以前这么多的值

posted on 2013-08-26 19:11  堕落华为人  阅读(2276)  评论(2编辑  收藏  举报

导航