c++语言绝对值函数,由C++绝对值函数想到的 – Mr.南柯 – 51Testing软件测试网 51Testing软件测试网-软件测试人的精神家园…

  • Post author:
  • Post category:其他

这些天恰好要用到一个绝对值的函数。好吧,你会说这个直接用std::abs不就行了吗?对的,一开始我也是这样用的。但是如果去求最小的那个int的值的绝对值,就会导致输出不正确。如:int min_int = -2147483648;51Testing软件测试网u)Y7D2Fu`p

cout<<:abs ql>

得到的结果仍然是-2147483648!恰好我的程序有可能出现这样的情况。所以需要自己去完成一个。EJE2[Xs3?/G0

7M%}+x+ufh8O01、第一个版本:bzV;Mz`ye%\EO0unsigned int __abs(int value)51Testing软件测试网$?’|l4ET$vgQ

{

9^*rHu`x0    return (value >= 0) ? value : -value;51Testing软件测试网)K4@gv|J[

}51Testing软件测试网#Ao{7A~

仍然是std::abs的老路,不可取!ug{+P1lfE0

HP5y.@z02、第二个版本:51Testing软件测试网3\_*AuP+ac3oWt&x(q+h?;M&hu:?0#include ]L \V2xI%[t051Testing软件测试网~X,T#BBaVi:R

unsigned int __abs(int value)

!c!rXcIc-U0{51Testing软件测试网#p’~~ E*D{0B

return (std::numeric_limits::min() == value || value >= 0) ? value : -value;

z”L4},a9L-X.}W/M0}”IP2~

j9^#g051Testing软件测试网I(pq’VHU

这个版本比较简洁,可移植性也很高。std::numeric_limits::min()返回当前系统下int值的最小值,能

够自适应int的内存宽度返回准确的值。当value和最小的int值相等或者value不为负数时,我们直接进行位对位的拷贝——因为unsigned

int没有符号位,所以完全可行的。当value为除最小值外的负数时,直接取相反数即可。51Testing软件测试网-[(\i@M.}9y3hY-O

3uO*YD;h@|,[0但这个版本需要用到两次条件判断,能不能再优化一下呢?所以出现了:51Testing软件测试网.NXO/yh{51Testing软件测试网im@|,}P

3、第三个版本:51Testing软件测试网H*T}e&a’Bunsigned int __abs(int value)51Testing软件测试网)f8|3s#A@%~R2a8nz

{

G2[r1LLK~0    unsigned int copyed_value = value;51Testing软件测试网R9Z*sd,mg&b

return (copyed_value > 0x80000000) ? -value : copyed_value;51Testing软件测试网/i6mWN

J8v

}

,nx)M5@}.`kvX0因为32位下最小的int值为0x80000000——最高位符号位为1。当位对位拷贝到unsigned

int中时,仍然是这个值。但其他的负数除了最高位为1外,其余位置也有值,比如-1的16进制表示为:0x80000001。所以,我们先执行位对位的

拷贝,到copyed_value中。所以出现了判断情况:E&~^1c}6eu9U8Pe+g9bL0

&lT UEX’]wQ:u”^0(1)如果copyed_value是大于0x80000000的,说明value是负数,所以我们直接取相反数(-value);51Testing软件测试网a[vHC8b X`q

zA#q^ V-y3a5c\0(2)如果copyed_value是等于0x80000000的,说明value恰好是最小的那个负数,执行位对位拷贝后,copyed_value中存放的就是value的绝对值,所以返回copyed_value;51Testing软件测试网z-~aMR;J.Y4[“K6H51Testing软件测试网*V(y3A9?SX&_

(3)如果copyed_value是小于0x80000000,说明value为正数。直接去alue或者copyed_value即可。51Testing软件测试网@|/\%d4|51Testing软件测试网V]%l~0wk

通过分析,我们将(2)和(3)合并到一起,返回copyed_value。所以,采取第三种方案,就只有一次比较操作。比第二种方案省一次。但是这种方案第一眼看去可能易读性上不是很好。51Testing软件测试网#B;in[4X,I

]51Testing软件测试网gx$^cQ[2@0Z

权衡三种方案,应该说各有利弊。三种情况各有适用的地方。如果你的函数不考虑最小int值的绝对值,可以采用std::abs即可;如果需要考虑但不必

担心性能问题,那么第二种方案是你最好的选择!但如果你既要考虑最小int值的绝对值问题,又要考虑性能问题,建议采用第三个方案。R2s8Sj;Cn-xX?’E051Testing软件测试网q5N

_Y5F

这个问题虽然简单,但里面透射出来的东西可真不少。其实我们在编程中,从细节出抓起,往往能够获得很多收获。51Testing软件测试网5D fi@fK

n7|R