由C++绝对值函数想到的
上一篇 / 下一篇 2012-09-17 15:21:00 / 个人分类:C++
int min_int = -2147483648;51Testing软件测试网#v9W.Vt:l!z$a R]$a cout<<std::abs(min_int)<<endl; |
得到的结果仍然是-2147483648!恰好我的程序有可能出现这样的情况。所以需要自己去完成一个。
*?-P4e x,b$b6k:a051Testing软件测试网9Pqm*b xzZ6TxU1、第一个版本:51Testing软件测试网p;Om j)gh*C1\\!u
unsigned int __abs(int value)51Testing软件测试网%\A
eG8YT {51Testing软件测试网.r:aBs7mM)z return (value >= 0) ? value : -value;51Testing软件测试网G^*Qk ` } |
仍然是std::abs的老路,不可取!
|:p5?2[bxkL;T0z\]Ev8zFye0 2、第二个版本:51Testing软件测试网*Q,vBZuL
51Testing软件测试网]-b(a/fE'H8o #include <limits> #Kd;e*A0usK1n+g0V&M)e)pc(}0unsigned int __abs(int value) |
这个版本比较简洁,可移植性也很高。std::numeric_limits<int>::min()返回当前系统下int值的最小值,能 够自适应int的内存宽度返回准确的值。当value和最小的int值相等或者value不为负数时,我们直接进行位对位的拷贝——因为unsigned int没有符号位,所以完全可行的。当value为除最小值外的负数时,直接取相反数即可。
){0m{&C2Br0L0z%M&q9{,fL-_%M0 但这个版本需要用到两次条件判断,能不能再优化一下呢?所以出现了:
#lh_zz |_0$m'K/dWH8Y@gq0 3、第三个版本:51Testing软件测试网|&C%I5v7e/s
unsigned int __abs(int value)51Testing软件测试网2BbW'}8GY4~] {51Testing软件测试网!{8`.iSeB/M8F unsigned int copyed_value = value;51Testing软件测试网 S'X{7q2Y"c&q return (copyed_value > 0x80000000) ? -value : copyed_value; c7B2g/Vt3Hd#F%v3~I0} |
因为32位下最小的int值为0x80000000——最高位符号位为1。当位对位拷贝到unsigned int中时,仍然是这个值。但其他的负数除了最高位为1外,其余位置也有值,比如-1的16进制表示为:0x80000001。所以,我们先执行位对位的 拷贝,到copyed_value中。所以出现了判断情况:51Testing软件测试网5ed,}!WfoZ6T%x&|
xdz,P,~x&R6j0 (1)如果copyed_value是大于0x80000000的,说明value是负数,所以我们直接取相反数(-value);51Testing软件测试网"^br@ySj
I4_[[%m`,Ri0 (2)如果copyed_value是等于0x80000000的,说明value恰好是最小的那个负数,执行位对位拷贝后,copyed_value中存放的就是value的绝对值,所以返回copyed_value;
/dr4AGZ/]051Testing软件测试网:}-{P#k_dh(3)如果copyed_value是小于0x80000000,说明value为正数。直接去alue或者copyed_value即可。