最近代碼中用到很多無符號(hào)整數(shù)的二元運(yùn)算,一直提心吊膽的,生怕什么時(shí)候加法運(yùn)算就溢出了。
所以有必要加個(gè)溢出檢測(cè)。
關(guān)于溢出,http://www.phrack.com/issues.html?issue=60&id=10,這篇文章講的很清楚。
檢測(cè)無符號(hào)整數(shù)相加溢出的方法比較簡(jiǎn)單:
首先在無符號(hào)表示中 a + 2^n = a;
如果a,b兩個(gè)無符號(hào)整數(shù),都未溢出:a < 2^n, b < 2^n, 且a+b > 2^n,
那么sum = a + b - 2^n , 即sum - a = b - 2^n < 0==> sum < a,同理可得 sum < b。
用這樣的方法可以判斷兩個(gè)無符號(hào)整數(shù)相加是否溢出,那么對(duì)于多個(gè)無符號(hào)整數(shù)相加,該怎么判斷呢?我現(xiàn)在想到的比較笨的辦法是兩兩相加然后判斷……
上段代碼,獻(xiàn)丑一下……
1 //! @brief check whether the usinged add will result in overflow 2 template<typename input_iterator> 3 int is_unsinged_add_overflow(input_iterator begin, 4 input_iterator last) 5 { 6 typedef typename Iterator_Traits<input_iterator>::value_type value_type; 7 if(!(boost::is_same<value_type,size_t>::value) 8 && !(boost::is_same<value_type,unsigned int>::value) 9 && !(boost::is_same<value_type,unsigned long>::value) 10 && !(boost::is_same<value_type,unsigned short>::value)){ 11 return -1; 12 } 13 std::stack<value_type> temp_sum; 14 input_iterator it = begin; 15 while(it != last){ 16 value_type a = *it++; 17 if(it == last) { 18 temp_sum.push(a); 19 break; 20 } 21 value_type b = *it++; 22 value_type sum = a + b; 23 if(sum < a || sum < b) return 0; // overflow 24 temp_sum.push(sum); 25 } 26 while(!temp_sum.empty()){ 27 if(temp_sum.size() == 1) return 1;// no overflow 28 std::stack<value_type> forwad_sum; 29 while(!temp_sum.empty()){ 30 value_type a = temp_sum.top(); 31 temp_sum.pop(); 32 if(temp_sum.empty()) forwad_sum.push(a); 33 else{ 34 value_type b = temp_sum.top(); 35 temp_sum.pop(); 36 value_type sum = a + b; 37 if(sum < a || sum < b) return 0; // overflow 38 forwad_sum.push(sum); 39 } 40 } 41 swap(temp_sum,forwad_sum); 42 } 43 }
麻煩的traits,補(bǔ)上自己的偏特化……
1 template <typename T> 2 struct Iterator_Traits 3 { 4 typedef typename T::value_type value_type; 5 }; 6 7 template <typename type> 8 struct Iterator_Traits<type*> 9 { 10 typedef type value_type; 11 };
代碼在ubuntu 11.04 64bit,g++-4.5.2下 編譯通過,寫的比較爛,請(qǐng)大家斧正~
浙公網(wǎng)安備 33010602011771號(hào)