6

我正在编写一个程序,可以计算高于 unsigned long long 的两个幂。基本上,我希望程序运行,然后在最后显示数字,但程序只有在每次乘以 2 后显示数字时才有效。这是工作方式的代码:

#include <iostream>
#include <stdio.h>
#include <climits>

using namespace std;

class big {
public:
    short container[SHRT_MAX];
    void print() {
        digits();
        for (; length != 0; length --) {
            cout << container[length - 1];
        }
        cout << "\n";
    }
    unsigned int digits() {
        if (!length) {
            for (length = 0; ; length++) {
                if (container[length] == '\0' &&container[length + 1] == '\0' && container[length + 2] == '\0' && container[length + 3] == '\0' && container[length + 4] == '\0') break;
            }
        }
        return length;
    }
private:
    unsigned int length;
};

int numDigits(int number)
{
    int digits = 0;
    if (number < 0) digits = 1;
    while (number) {
        number /= 10;
        digits++;
    }
    return digits;
}

int main(int argc, const char * argv[])
{
    big result;
    unsigned short tempResult;
    unsigned short carry = 0;
    result.container[0] = 1;

    for (int i = 0; i < 65536; i++) {
        cout << "[" << i+1 << "]\t";
        if (i < 9) {
            cout << "\t";
        }

        carry = 0;
        unsigned int length = result.digits();
        for (int k = 0; k < length; k++) {
            tempResult = result.container[k] * 2 + carry;
            carry = 0;
            if (numDigits(tempResult) == 2) {
                carry = 1;
                result.container[k] = tempResult - 10;
                if (!result.container[k+1] && !result.container[k+2] && !result.container[k+3] && !result.container[k+4]) {
                    result.container[k+1] += carry;
                }
            }
            else {
                result.container[k] = tempResult;
            }
        }
        result.print();
    }
}

我想result.print()在程序结束后运行,而不是在运行时运行。我知道该怎么做,但是当我把result.print()输出放在循环之外时6,没有别的了。任何帮助将不胜感激,如果您需要澄清,请提出问题。

4

3 回答 3

3

在构建“大”对象期间,您的成员被默认初始化,而不是值初始化。digits()因此,当您调用计算长度时,该数组中的任何垃圾和长度都将被用作有效。

将以下内容添加到class big

big() : length(0) { memset(container, 0, sizeof(container)); }

即使那样,结果计算仍然存在堆栈溢出问题。这个:

if (!result.container[k+1] && !result.container[k+2] && !result.container[k+3] && !result.container[k+4]) {
    result.container[k+1] += carry;

几乎可以保证超出您有限的数字容器足够大length(并且不会花费太多)。

您实际上是在这个类中完成了一半的工作,而一半是在直接修改这个类的成员的代码中完成的。并且几乎违反了人们能想到的每一个 OOP 口头禅。坦率地说,这非常需要重新设计。

示例输出(我将其限制为 128 个条目)

[1]     2
[2]     4
[3]     8
[4]     6
[5]     32
[6]     64
[7]     28
[8]     256
[9]     512
[10]    024
[11]    2048
[12]    4096
[13]    8192
[14]    6384
[15]    32768
[16]    65536
[17]    31072
[18]    262144
[19]    524288
[20]    048576
[21]    2097152
[22]    4194304
[23]    8388608
[24]    6777216
[25]    33554432
[26]    67108864
[27]    34217728
[28]    268435456
[29]    536870912
[30]    073741824
[31]    2147483648
[32]    4294967296
[33]    8589934592
[34]    7179869184
[35]    34359738368
[36]    68719476736
[37]    37438953472
[38]    274877906944
[39]    549755813888
[40]    099511627776
[41]    2199023255552
[42]    4398046511104
[43]    8796093022208
[44]    7592186044416
[45]    35184372088832
[46]    70368744177664
[47]    40737488355328
[48]    281474976710656
[49]    562949953421312
[50]    125899906842624
[51]    2251799813685248
[52]    4503599627370496
[53]    9007199254740992
[54]    8014398509481984
[55]    36028797018963968
[56]    72057594037927936
[57]    44115188075855872
[58]    288230376151711744
[59]    576460752303423488
[60]    152921504606846976
[61]    2305843009213693952
[62]    4611686018427387904
[63]    9223372036854775808
[64]    8446744073709551616
[65]    36893488147419103232
[66]    73786976294838206464
[67]    47573952589676412928
[68]    295147905179352825856
[69]    590295810358705651712
[70]    180591620717411303424
[71]    2361183241434822606848
[72]    4722366482869645213696
[73]    9444732965739290427392
[74]    8889465931478580854784
[75]    37778931862957161709568
[76]    75557863725914323419136
[77]    51115727451828646838272
[78]    302231454903657293676544
[79]    604462909807314587353088
[80]    208925819614629174706176
[81]    2417851639229258349412352
[82]    4835703278458516698824704
[83]    9671406556917033397649408
[84]    9342813113834066795298816
[85]    38685626227668133590597632
[86]    77371252455336267181195264
[87]    54742504910672534362390528
[88]    309485009821345068724781056
[89]    618970019642690137449562112
[90]    237940039285380274899124224
[91]    2475880078570760549798248448
[92]    4951760157141521099596496896
[93]    9903520314283042199192993792
[94]    9807040628566084398385987584
[95]    39614081257132168796771975168
[96]    79228162514264337593543950336
[97]    58456325028528675187087900672
[98]    316912650057057350374175801344
[99]    633825300114114700748351602688
[100]   267650600228229401496703205376
[101]   2535301200456458802993406410752
[102]   5070602400912917605986812821504
[103]   0141204801825835211973625643008
[104]   20282409603651670423947251286016
[105]   40564819207303340847894502572032
[106]   81129638414606681695789005144064
[107]   62259276829213363391578010288128
[108]   324518553658426726783156020576256
[109]   649037107316853453566312041152512
[110]   298074214633706907132624082305024
[111]   2596148429267413814265248164610048
[112]   5192296858534827628530496329220096
[113]   0384593717069655257060992658440192
[114]   20769187434139310514121985316880384
[115]   41538374868278621028243970633760768
[116]   83076749736557242056487941267521536
[117]   66153499473114484112975882535043072
[118]   332306998946228968225951765070086144
[119]   664613997892457936451903530140172288
[120]   329227995784915872903807060280344576
[121]   2658455991569831745807614120560689152
[122]   5316911983139663491615228241121378304
[123]   0633823966279326983230456482242756608
[124]   21267647932558653966460912964485513216
[125]   42535295865117307932921825928971026432
[126]   85070591730234615865843651857942052864
[127]   70141183460469231731687303715884105728
[128]   340282366920938463463374607431768211456
于 2013-09-15T12:56:25.700 回答
1

好的,我不会说这是我的最终解决方案,因为我仍然不知道为什么这是真的,但是当我设置result.length为 0 时,我可以在循环之外打印最终解决方案。这是代码:

#include <iostream>
#include <stdio.h>
#include <climits>

using namespace std;

class big {
public:
    short container[SHRT_MAX];
    void print() {
        digits();
        for (; length != 0; length --) {
            cout << container[length - 1];
        }
        cout << "\n";
    }
    void resetLength() {
        length = 0;
    }
    unsigned int digits() {
        length = 0;
        for (length = 0; ; length++) {
            if (container[length] == '\0' &&container[length + 1] == '\0' && container[length + 2] == '\0' && container[length + 3] == '\0' && container[length + 4] == '\0') break;
        }
        return length;
    }
    big() : length(0) { memset(container, 0, sizeof(container)); }
private:
    unsigned int length;
};

int numDigits(int number)
{
    int digits = 0;
    if (number < 0) digits = 1;
    while (number) {
        number /= 10;
        digits++;
    }
    return digits;
}

int main(int argc, const char * argv[])
{
    big result;
    unsigned short tempResult;
    unsigned short carry = 0;
    result.container[0] = 1;

    for (unsigned int i = 0; i < 65536; i++) {
        /*cout << "[" << i+1 << "]\t";
        if (i < 9) {
            cout << "\t";
        }*/

        carry = 0;
        unsigned int length = result.digits();
        for (int k = 0; k < length; k++) {
            tempResult = result.container[k] * 2 + carry;
            carry = 0;
            if (numDigits(tempResult) == 2) {
                carry = 1;
                result.container[k] = tempResult - 10;
                if (!result.container[k+1] && !result.container[k+2] && !result.container[k+3] && !result.container[k+4]) {
                    result.container[k+1] += carry;
                }
            }
            else {
                result.container[k] = tempResult;
            }
        }
        result.resetLength();
    }
    result.print();
}

谁能解释这是如何或为什么起作用的?

于 2013-09-15T14:08:07.997 回答
1

print()和你digits()只能一起工作。

只有当它为零时才digits()计算一个新的。length否则它什么也不做。print()您在每次迭代中编写它的地方的函数length等于0

当您移出打印时,每次下一次迭代length都不等于,因此长度保持不变(第一次迭代后为 1)。0

实际上,这样写并不是一个好主意print()。这意味着您只能打印一次数字。您应该为此使用局部变量。

于 2013-09-15T13:01:04.407 回答