I am writing a program that can calculate powers of two that are higher than unsigned long long. Basically, I want the program to run and then show the number at the end, but the program only works if I show the number after every time I multiply it by two. Here is the code for the working way:
#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()
to be run after the program is over, not while it is running. I know how to do that, but when I put result.print()
outside of the loop the output is 6
and nothing else. Any help would be greatly appreciated and please ask questions if you need clarification.
Your members are being default-initialized, and not value-initialized during construction of your "big" object. Consequently, whatever junk is in that array and length is then being used-as-though-valid when you invoke digits()
to compute the length.
Add the following to class big
:
big() : length(0) { memset(container, 0, sizeof(container)); }
Even then you still have a stack-overflow issue with the result calculation. This:
if (!result.container[k+1] && !result.container[k+2] && !result.container[k+3] && !result.container[k+4]) {
result.container[k+1] += carry;
is all-but-guaranteed to overrun your limited digit container for sufficiently large length
(and it isn't going to take much).
You're doing literally half your work in this class, and half in code directly modifying members of this class. and violating near-every OOP mantra one can think of. To be completely frank, this needs a redesign badly.
Sample Output (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
Your print()
and your digits()
can work only together.
The digits()
calculates a new length
only if it is zero. Otherwise it does nothing.
The print()
function in the place that you write it every iteration makes length
equal to 0
.
When you move out the printing, length
is not equal to 0
at each next iteration, so length stays the same (1 after the first iteration).
Actually it is not a good idea write the print()
this way. That means that you can print a number only one time. You should use a local variable for it.
Okay I am not going to say this is my final solution because I still don't know why that is true, but when I set result.length
to 0, I can print the final solution outside of 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 anyone explain how or why this works?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With