【问题标题】:multiplying two large numbers in C / C++在 C/C++ 中将两个大数相乘
【发布时间】:2012-09-05 22:33:26
【问题描述】:

我试图想出解决方案...两个大数 abchar[]char* 表示,目标是将它们乘以第三个指针, char* c:

void multiply( const char* a, const char* b ){
    int len_a = strlen( a );
    int len_b = strlen( b );
    int* c = new int[ len_a + len_b];
    memset( c, 0, sizeof(int) * ( len_a + len_b ));

    for( int i = len_a - 1; i >= 0; i-- ){
        for( int j = len_b - 1; j >= 0; j-- ){
            c[ i + j + 1 ] += ( b[ j ] - '0') * ( a[ i ] - '0' );
        }
    }

    for( int i = len_a + len_b; i >= 0; i-- ){
        if( c[ i ] >= 10 ){
            c[ i - 1 ] += c[ i ] / 10;
            c[ i ] %= 10;
        }
    }

    cout << a << " * " << b << " = " << c << endl;
    delete[] c;
}

我写了上面的函数来为我做这个操作......但是,当我使用输入时:

int main( void ){
    const char* a = "999";
    const char* b =  "99999";
    multiply( a, b );
    // I expect the answer to be 1 and 6
    // profit = 0.92
    return 0;
}

我明白了:

999 * 99999 = 0x100100080

为什么我得到的是内存地址而不是实际数字? 谢谢!

【问题讨论】:

  • int *c,当你输出时它会输出指针。你不是说要char *c吗?
  • 哦,很奇怪——旧的“我喜欢内存泄漏、双重删除和缓冲区溢出”的代码风格。
  • @BobFincheimer:是的,我想以char* c 的身份进行操作。你能给我一个想法,我怎么能把它写成一个字符?
  • @DeadMG 我在他的代码中没有看到任何这些。
  • @BobFincheimer,如果有人翻转了cout 的异常掩码位怎么办?这种类型的代码没有理由更喜欢new[] 而不是vector

标签: c++ iostream bignum


【解决方案1】:

因为c 是一个int 指针,如果传递了这样一个指针,cout 的流运算符将打印一个内存地址。要获得值,您需要取消引用指针,例如*c。您可能需要编写一个循环来打印整个整数“字符串”。

【讨论】:

  • 但是他像char *一样使用c,再看一遍,我认为他的意思是让c成为char *,而不是int *
  • 他使用 int* 是因为它是他累积中间乘法结果的地方。如果他使用 char*,就会溢出。
  • 猜测他是在使用int 以某种方式为结果留出空间,但也许你是对的。他确实说他想要char* 结果,但他的函数实际上只是让c 超出范围并返回void,所以很难说。
【解决方案2】:
cout << a << " * " << b << " = ";
    for( int i = 0; i < len_a + len_b; i++ ){
        cout << c[ i ];
    }

    cout << endl;

会产生想要的结果...

【讨论】:

    【解决方案3】:

    你的逻辑是正确的。 快速提醒一下:当您创建一个整数指针并将其用作数组时,它指向“数组的第一个元素”,因此当您打印它时,您会看到数组 c 的第一个元素的地址,在你的情况下是“0x100100080”。

    要打印存储在 c 中的数字(字符),您需要取消引用指针,即一个接一个地打印数组中的元素。或者,您可以将数组转换为数字并立即打印。后者请参考:How to convert array of integers into an integer in C?。 要逐个打印字符,您可以替换

    std::cout<<c; 
    

    使用以下代码:

    int n=strlen(c);
    for(int i=0; i<n; i++) {
        std::cout<<c[i];
    }
    

    这将打印数字。

    【讨论】:

      【解决方案4】:

      std::ostreamstd::cout 是其中的类型)没有任何专门针对int* 的重载运算符,因此它回退到void* 重载,它只是以实现定义的方式输出指针值.

      此外,int* 重载无法确定指针指向数组,更进一步,无法确定这样的数组有多少元素。

      【讨论】:

      • 我将如何为char* 执行此操作?
      【解决方案5】:

      for(c++14) 我们可以使用 boost 库..

      #include <iostream>
      #include <boost/multiprecision/cpp_int.hpp>
      namespace mp = boost::multiprecision;
      int main()
      {
        mp::cpp_int s1("12368123681263817263863821638126328136218362182");
        mp::cpp_int s2("345897937325785470923092923709887329092470423707534025");
        mp::cpp_int S=s1*s2;
        std::cout << S << '\n';
        }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多