C ++程序仅在打印数字时有效

时间:2013-09-15 12:32:36

标签: c++

我正在编写一个程序,可以计算出高于无符号long long的2的幂。基本上,我希望程序运行,然后在最后显示数字,但程序只有在我每次将它乘以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而没有其他内容。任何帮助将不胜感激,如果您需要澄清,请提出问题。

3 个答案:

答案 0 :(得分: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

答案 1 :(得分:1)

您的print()digits()只能在一起工作。

digits()仅在零length时计算新print()。否则它什么都不做。 每次迭代时编写的length函数都会使0等于length

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

实际上以这种方式写{{1}}并不是一个好主意。这意味着您只能打印一次数字。你 应该使用局部变量。

答案 2 :(得分: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();
}

任何人都可以解释这是如何或为何起作用的?