2011-04-03 36 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

相关问题