C ++ program only works if number is printed

I am writing a program that can calculate the powers of two that are greater than unsigned long long. Basically, I want the program to start and then show the number at the end, but the program only works if I show the number after each multiplication by two. Here is the code for the working path:

#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(); } } 

I want result.print() start after the program finishes, and not while it starts. I know how to do this, but when I put result.print() outside the loop, output 6 and nothing else. Any help would be greatly appreciated and please ask questions if you need clarification.

+6
source share
3 answers

Your members are initialized by default, and not initialized by value when you create your "large" object. Therefore, no matter how much garbage in this array and length is used, it is as if valid when you call digits() to calculate the length.

Add the following to class big :

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

Even then, you still have a stack overflow problem with calculating the result. It:

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

still guaranteed to overlap your container with a limited icon for a sufficiently large length (and it will not take much time).

You do literally half of your work in this class, and half in code, directly modifying the members of this class. and violating almost every OOP mantra you might think of. To be completely frank, it needs a bad redesign.

Output result (I limited it to 128 entries)

 [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 
+3
source

Your print() and your digits() can only work together.

digits() computes the new length only if it is zero. Otherwise, he does nothing. The print() function in the place where you write it at each iteration makes length equal to 0 .

When you go out of print, length not 0 at each next iteration, so the length remains the same (1 after the first iteration).

It is actually not so good to write print() in this way. This means that you can print the number only once. You must use a local variable for it.

+1
source

Well, I won’t say that this is my final decision, because I still don’t know why this is true, but when I set result.length to 0, I can print the final solution outside the loop. Here is the code:

 #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(); } 

Can someone explain how and why this works?

+1
source

Source: https://habr.com/ru/post/953856/


All Articles