Hello, I am new here.. I came here looking for help with some ACPP questions and found a couple. So now, hopefully, I can give back a little, but with a question!

Here is my solution for ACPP Exercises 4-2 through 4-4 (sort of, I havent switched it to use doubles yet).

Anyways, for anyone curious, here are the questions..


4-2. Write a program to calculate the squares of int values up to 100. The program should write two columns: The first lists the value; the second contains the square of that value. Use setw (described above) to manage the output so that the values line up in columns.

4-3. What happens if we rewrite the previous program to allow values up to but not including 1000 but neglect to change the arguments to setw? Rewrite the program to be more robust in the face of changes that allow i to grow without adjusting the setw arguments.

4-4. Now change your squares program to use double values instead of ints. Use manipulators to manage the output so that the values line up in columns.

So, what I eventually did was make the question ask for the max integer to create squares of up to, and the max square to display (4-3?).

My question is, was it overkill to add the checking if the sqrt of 'cutoff' is larger than 'max' than to make 'cutoff' = 'max'.

The reason I decided to do this was to not makiea vector that may be too large, specifically if it wasnt going to be displayed.. make sense?

Anyways, i was stuck on this problem for a while and this is what I finally came up with.. any advice or tips on how I could improve this?? Am i wrong in my assumption of trying to save cycles by not writing to the vector if its not necessary??

Thanks!

#include <iostream>
#include <vector>
#include <iomanip>
#include <math.h>

using namespace std;

int main()
{
    int x, max, sqWidth, iWidth, cutoff = 0;
    vector<int> squares;

    while (cutoff <= 0 ) {
        cout << "Enter cutoff square to output: ";
        cin >> cutoff;
    }

    while (max <= 0 ) {
        cout << "Enter max number to calcate squares up to: ";
        cin >> max;
    }

    if (sqrt(cutoff) < max) {
        max = sqrt(cutoff);
    }

    for (int i=0; i != max; i++) {
        x = (i+1) * (i+1);
        squares.push_back(x);
    }

    iWidth = log10(max)+1;
    sqWidth = log10(squares[max-1])+1;

    x = 0;
    while (squares[x] < cutoff && x != max) {
        cout << setw(iWidth) << x+1 << " " << setw(sqWidth) << squares[x] << endl;
        x++;
    }

    for (int i = 0; i < max; i++) {
        cout << setw(iWidth) << i+1 << " " << setw(sqWidth) << squares[i] << endl;
        i++;
    }
}

Dani AI

Generated

Nice experimentation by and a good nudge from to keep the interface simple. A few concrete points to make the program correct, robust and easy to maintain:

  • Critical bug: max is read before it’s initialized (the while (max <= 0) loop). That causes undefined behavior. Always initialize variables used in conditions (for example int max = 0;). Also check stream state after input and handle non-numeric input.
  • Bounds & ordering: never index squares[x] before confirming x is in range. Use the index check first (e.g. x < squares.size() && squares[x] <= cutoff) so short-circuiting prevents out-of-range access. The final for in the posted code also increments i twice — remove the extra i++ inside the loop body.
  • Allocation & performance: if the final count is known, prefer resize (or at least reserve) and fill by index rather than repeated push_back to avoid reallocations. If the goal is only to print up to cutoff, compute until the next square exceeds cutoff and stop — no need to precompute everything. These are simple choices that save work without premature micro-optimizations.
  • Formatting and types: avoid expensive math where unnecessary. For column widths, using std::to_string(value).length() is simpler and robust across changes than playing with log10. When switching to double (exercise 4-4) print with std::fixed + std::setprecision(...) and measure the formatted string length for alignment. Watch integer overflow when squaring: with 32-bit int, n > 46340 will overflow; use long long or check limits if larger ranges are allowed.

These tweaks keep the code safe and clear while preserving the learning value of the exercise. Experimenting with both inputs was fine for learning; in practice, prefer a single, well-validated input or derive the effective calculation limit and document the behavior.

Recommended Answers

All 5 Replies

No feedback?

You're asking two questions when one question will suffice, so I would say it's overkill. Ask either of these:

Input largest value to square :

or

Input largest squared value :

but not both because one derives from the other. Frankly I think the first question is easier for the user to understand. You can have some maximum value and check against it:

bool haveMaxValue = false;
const int MAX_ALLOWED_CUTOFF = 1000;
int cutoff;

while (!haveMaxValue)
{
     cout << "Enter largest value to square : ";
     cin >> cutoff;

     if (cutoff < 0 || cutoff > MAX_ALLOWED_CUTOFF)
     {
         cout << "Please enter a non-negative value <= ";
         cout << MAX_ALLOWED_CUTOFF << endl;
     }
     else
         haveMaxValue = true;
}

If you can ask one question instead of two, do it.

Thanks VD. Agreed that I could have gotten away with just setting the max square to display as a const int. But, in the interest of learning I wanted to make it an entered variable so I could see how setting it to different values would affect the vector of squares.

You may notice that I calculate all the squares up to the max number and store them in a vector. Then I display the vector twice, first using the cutoff of the square to display and second, the entire vector, formatting the column widths with depending on how many digits are in the largest cutoff amount and the max value.

Then, I found that if I set the max square to caclulate up to was say 500, but I set my cutoff to dislpay only up to 1000 if found the vector still stored squares 1 - 500, but wouldnt show all of them (expectedly) - hence why I checked to see if the sqrt(cutoff) is smaller than the max value.. and if so set max to that so, result being it doesnt create a vector with a whole bunch of squares that will never be displayed.

I was just curious if this a valid tactic when optimizing c++ code, or am I just totally over engineering this thing? I did learn a lot though!

Thanks VD. Agreed that I could have gotten away with just setting the max square to display as a const int. But, in the interest of learning I wanted to make it an entered variable so I could see how setting it to different values would affect the vector of squares.

You may notice that I calculate all the squares up to the max number and store them in a vector. Then I display the vector twice, first using the cutoff of the square to display and second, the entire vector, formatting the column widths with depending on how many digits are in the largest cutoff amount and the max value.

Then, I found that if I set the max square to caclulate up to was say 500, but I set my cutoff to dislpay only up to 1000 if found the vector still stored squares 1 - 500, but wouldnt show all of them (expectedly) - hence why I checked to see if the sqrt(cutoff) is smaller than the max value.. and if so set max to that so, result being it doesnt create a vector with a whole bunch of squares that will never be displayed.

I was just curious if this a valid tactic when optimizing c++ code, or am I just totally over engineering this thing? I did learn a lot though!

It's definitely not optimal. One, calculating the square root is unnecessary. Calculate the squares. I have to believe that's a much faster operation. I see nothing in the specification that says you need to calculate the square root of anything. Ditto the logarithms. Why are you calculating the logarithms? That's another unnecessary, computationally expensive calculation. Finally, if you are optimizing, take advantage of the fact that you know EXACTLY how many squares you need to calculate and make your vector that size if you want to use a vector. Right now, using push_back, you force the compiler to guess, then when its guess is wrong, resize the vector. That's inefficient. When you KNOW the size, and you do here because the user enters it, SPECIFY the size. it takes all the guesswork out.

[EDIT]
OK, I see your reasoning behind the logarithms now, so that's not bad. Regarding efficiency/optimization, though, please take a look at the rest of my post.
[/EDIT]

Thannks again VD, makes sense. Lessons are, when optimizing is to take advantage of explicitly declared numbers, sqrt is a CPU intensize function, ram is cheap :)

Cheers!

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.