2011-04-03 59 views
0

想法是重載operator *,以便它可以乘以代表數字十進制值的兩個字符串。操作員是一個更大的班級的一部分,但這並不重要。該算法是一樣的小學:)代表數字十進制值的2個字符串的C++乘法

這裏是我的代碼:

Bignumber operator* (Bignumber x, Bignumber y){ 
    int i, j, transfer=0, tmp, s1, s2, k; 
    char add[1]; 
    string sol; 
    string a, b; 
    Bignumber v1, v2; 
    a=x.GetValue(); 
    b=y.GetValue(); 

    a.insert(0,"0"); 
    b.insert(0,"0"); 

    for(i=a.length()-1; i>=0; i--){ 
     s1 = (int) a[i]-48; 
     for(k=a.length()-i-1; k >0 ; k--){ 
      sol+="0"; 
     } 
     for(j=b.length()-1; j >=0; j--){ 
      s2=(int) b[j]-48; 
      tmp=s1*s2+transfer; 
      if(tmp >= 10){ 
       transfer=tmp/10; 
       tmp=tmp-(10*transfer); 
      } 
      itoa(tmp, add, 10); 
      sol.insert(0, add); 
     } 
     v1=sol; 
     v2=v1+v2; 
     sol.erase(0); 
     transfer=0; 
    } 
    return v2; 
} 

也能正常工作的大部分時間,但對於一些隨機值它不正常工作。例如對於128 * 28,它返回4854而不是3584.

任何想法可能是什麼問題?

operator s +=已經超載爲類Bignumber,他們工作正常。

+2

你爲什麼使用字符串表示? 「Bignumber」類最有可能具有在某些基數中暴露「數字」的表示(例如,65536)。 – Vlad 2011-04-03 16:34:35

+0

多數民衆贊成那不是問題在這裏..我需要找出爲什麼它不工作:) – boone 2011-04-03 16:39:28

+2

prenos沒有定義,tmp使用時未經初始化,這是一個愚蠢的做法 – 2011-04-03 16:51:01

回答

3

雖然我的第一個答案可以解決您的問題(無論如何,通過我的測試),下面是一個替代實現;我沒有你的Bignumber班,所以我寫了一個小的假的測試:

#include <string> 
#include <ios> 
#include <iostream> 
#include <ostream> 
#include <sstream> 

class Bignumber 
{ 
    static inline unsigned long long strtoull(std::string const& str) 
    { 
     unsigned long long val; 
     return std::istringstream(str) >> val ? val : 0uLL; 
    } 

    unsigned long long val_; 

public: 
    Bignumber() : val_() { } 
    explicit Bignumber(unsigned long long const val) : val_(val) { } 
    explicit Bignumber(std::string const& str) : val_(strtoull(str)) { } 

    Bignumber& operator +=(Bignumber const rhs) 
    { 
     val_ += rhs.val_; 
     return *this; 
    } 

    std::string GetValue() const 
    { 
     std::ostringstream oss; 
     oss << val_; 
     return oss.str(); 
    } 
}; 

Bignumber operator *(Bignumber const x, Bignumber const y) 
{ 
    typedef std::string::const_reverse_iterator cr_iter_t; 

    std::string const& a = '0' + x.GetValue(); 
    std::string const& b = '0' + y.GetValue(); 

    Bignumber ret; 
    for (cr_iter_t a_iter = a.rbegin(), a_iter_end = a.rend(); a_iter != a_iter_end; ++a_iter) 
    { 
     unsigned transfer = 0u; 
     std::string sol(a.end() - a_iter.base(), '0'); 
     for (cr_iter_t b_iter = b.rbegin(), b_iter_end = b.rend(); b_iter != b_iter_end; ++b_iter) 
     { 
      unsigned tmp = static_cast<unsigned>(*a_iter - '0') * static_cast<unsigned>(*b_iter - '0') + transfer; 
      if (tmp >= 10u) 
      { 
       transfer = tmp/10u; 
       tmp -= transfer * 10u; 
      } 
      sol.insert(sol.begin(), static_cast<char>(tmp + '0')); 
     } 
     ret += Bignumber(sol); 
    } 
    return ret; 
} 

int main() 
{ 
    Bignumber const z = Bignumber(123456789uLL) * Bignumber(987654321uLL); 
    std::cout << std::boolalpha << (z.GetValue() == "121932631112635269") << std::endl; 
} 
1

itoa null-terminated它寫入的字符串,所以add對於寫入的數據太小,導致內存損壞。將add的定義更改爲char add[2];,它應該可以工作。

+0

感謝您的回覆。我試圖改變添加到2的大小,但它仍然沒有工作 – boone 2011-04-03 17:43:31

+0

@boone:沒有工作的'x'和'y'的值是什麼?它在本地分別用'1234'和'5678'工作。 – ildjarn 2011-04-03 17:58:08

相關問題