Efficient Array Initialization in Visual C++ for a 4-Digit Odometer

  • Context: C/C++ 
  • Thread starter Thread starter LCKurtz
  • Start date Start date
  • Tags Tags
    Array C++ Visual
Click For Summary

Discussion Overview

The discussion revolves around efficiently initializing a 4-digit odometer represented as a 4-column array, using digits from 0 to 7. Participants explore various coding approaches in C++ within the Microsoft Visual Studio environment, focusing on performance and memory usage.

Discussion Character

  • Exploratory
  • Technical explanation
  • Debate/contested
  • Mathematical reasoning

Main Points Raised

  • One participant describes the need to create a 4-column array for a 4-digit odometer, specifying the range of values from 0000 to 7777.
  • Another participant suggests that writing a code snippet would be more beneficial for learning than simply receiving a solution.
  • A participant proposes using four nested loops to fill the array, noting that modern computers can handle this efficiently.
  • Some participants suggest that if the octal counters are stable, generating counts directly from the index could be more efficient than using an array.
  • One participant provides a code snippet that initializes the array using division and modulus operations to extract digits from the index.
  • Another participant presents a different approach using nested loops, while also mentioning potential performance concerns with this method.
  • Concerns are raised about the necessity of storing all values in memory, with suggestions that on-the-fly calculations might be more efficient.
  • A function is proposed that calculates the digit values directly from the row and column indices, arguing it could be faster than accessing a lookup table.

Areas of Agreement / Disagreement

Participants express differing views on the necessity and efficiency of using an array versus calculating values on-the-fly. There is no consensus on the best approach, as various methods are discussed and debated.

Contextual Notes

Some participants highlight the potential inefficiency of using a large lookup table for simple calculations, while others emphasize the learning aspect of seeing examples from experienced programmers. The discussion reflects a range of opinions on coding practices and performance considerations.

Who May Find This Useful

This discussion may be useful for programmers interested in C++ array manipulation, performance optimization, and those exploring different coding strategies for similar problems.

LCKurtz
Science Advisor
Homework Helper
Messages
9,567
Reaction score
775
Let's say you have a 4 digit "odometer" using just the digits 0 through 7. So it starts at 0000 and works its way up to 7777. So, for example, the next reading after 0007 is 0010 etc. There are ##8^4 = 4096## readings before it rolls over. I want to create and initialize an array with ##4096## rows and ##4## columns with the elements of each row being the corresponding digits (integer type). Like this:$$
\begin {bmatrix}
0 & 0 & 0 & 0\\
0 & 0 & 0 & 1\\
& & \cdots & \\
7 & 7 & 7 & 6\\
7 & 7 & 7 & 7
\end {bmatrix}$$
I'm just experimenting with C##^{++}## in Microsoft Visual Studio. A code snippet for this would save me a lot of time and likely be more efficient than what I might come up with.
 
Technology news on Phys.org
It would save you a lot of time, but would defeat the purpose of you learning how the code works. Why don't you write a code snippet and let us critique it?
 
  • Like
Likes   Reactions: Klystron and Dr Transport
phyzguy said:
It would save you a lot of time, but would defeat the purpose of you learning how the code works. Why don't you write a code snippet and let us critique it?
Because it's part of an almost pointless personal project, because although I have written lots of software over the years, the C##^{++}## environment is new to me, because I am retired and I have no need to "learn how the code works", and because when (if I bother to) I slog through the new environment for the proper headers and syntax to get it working, I won't need your critique. And I also happen to know that one of the best ways to learn a new environment is to see examples from others who already know. That's why.
 
LCKurtz said:
Because it's part of an almost pointless personal project, because although I have written lots of software over the years, the C##^{++}## environment is new to me, because I am retired and I have no need to "learn how the code works", and because when (if I bother to) I slog through the new environment for the proper headers and syntax to get it working, I won't need your critique. And I also happen to know that one of the best ways to learn a new environment is to see examples from others who already know. That's why.

Until you slog through getting headers etc going in C/C++, reading someone else's code isn't going to help very much. I tried your approach years ago and until I did it, my C/C++ ability was lacking.
 
I can't, offhand, think of any "slick" way to do that. Any simple way you have is probably as good as any. Clearly, four nested loops from 0 to 7 would do it. Modern computers are so fast that they can fill that array in a millisecond. So unless this is something that will be done a very great number of times, I would leave it simple.
 
Last edited:
  • Like
Likes   Reactions: hmmm27
If your octal counters are a stable part of your problem domain (i.e. you don't later want to change that to another base), then you may want skip the array and just generate the four counts from the index directly. And in that case you may also want to look up bit fields (hint: it should be possible to generate the four counts directly from a type cast from an int index to a struct with four bit fields).
 
  • Like
Likes   Reactions: Klystron
Combining the two previous posts, your simplest solution appears to be that computing the indices for the hypothetical matrix already gives you the counter value at that index.
 
  • Like
Likes   Reactions: Mark44
LCKurtz said:
Because it's part of an almost pointless personal project, because although I have written lots of software over the years, the C##^{++}## environment is new to me, because I am retired and I have no need to "learn how the code works", and because when (if I bother to) I slog through the new environment for the proper headers and syntax to get it working, I won't need your critique. And I also happen to know that one of the best ways to learn a new environment is to see examples from others who already know. That's why.

The problem you're asking about has nothing special to do with the Microsoft Visual Studio environment.

Here's one way to do what you're asking:
C++:
unsigned int digits[4096][4];

for (unsigned int i=0; i<4096; ++i) {
    digits[i][0] = (i / 512) % 8;
    digits[i][1] = (i / 64) % 8;
    digits[i][2] = (i / 8) % 8;
    digits[i][3] = i % 8;
}
Since the base happens to be a power of 2, you can alternatively get the digits out of the index with bit operations. E.g., do (i >> 3) & 07 instead of (i / 8) % 8. But that's a bit more cryptic and less general.

Also, in the name "C++", the "++" is not a superscript.
 
Last edited:
  • Like
  • Informative
Likes   Reactions: LCKurtz, Klystron and DavidSnider
wle said:
The problem you're asking about has nothing special to do with the Microsoft Visual Studio environment.

Here's one way to do what you're asking:
C++:
unsigned int digits[4096][4];

for (unsigned int i=0; i<4096; ++i) {
    digits[i][0] = (i / 512) % 8;
    digits[i][1] = (i / 64) % 8;
    digits[i][2] = (i / 8) % 8;
    digits[i][3] = i % 8;
}
Since the base happens to be a power of 2, you can alternatively get the digits out of the index with bit operations. E.g., do (i >> 3) & 07 instead of (i / 8) % 8. But that's a bit more cryptic and less general.

Also, in the name "C++", the "++" is not a superscript.

Thank you. That is very useful.
 
  • #10
Here's a different approach from the one presented by @wle, that uses the idea hinted at by @Klystron. This code will fill the array with 0000, 0001, 0002, ... , 7777.
Nested loops aren't ideal for performance, as they cause the CPU pipeline to be invalidated, but I don't think this is a concern for this problem.

C:
const unsigned short MAX = 8;
const unsigned int ROWS = 4096;
unsigned short arr[ROWS][4];

int main()
{
  int rowNum = 0;
  for (unsigned short d0 = 0; d0 < MAX ; d0++)          // Thousands place
      for (unsigned short d1 = 0; d1 < MAX; d1++)        // Hundreds place
         for (unsigned short d2 = 0; d2 < MAX; d2++)     // Tens place
            for (unsigned short d3 = 0; d3 < MAX; d3++)  // Ones place
            {
                rowNum++;
                arr[rowNum][0] = d0;
                arr[rowNum][1] = d1;
                arr[rowNum][2] = d2;
                arr[rowNum][3] = d3;
           }
}
 
  • Informative
Likes   Reactions: Klystron
  • #11
I have to admit, the proffered code is giving me a blepharospasm ; yeah, I know, "run once", "optimizing compiler". Still ...

What is the actual application ? On-the-fly would probably be more efficient than a 2d-table access, and more elegant than loading said table, for anything I can think of offhand...
 
  • Like
Likes   Reactions: Klystron
  • #12
I'm not sure why you would ever want to put all of that into memory. You're storing 16kb of information to store a lookup table for a formula involving 3 of the simplest CPU functions. Lookup tables tend to be used for more complicated maths like trig.

Code:
unsigned int digits(int row, int column){
     return (row >> (column << 8)) & 07;  //untested but should produce the same results as everything above
}

When I think about it, this particular function call would almost certainly be faster than calling a lookup table because that would imply: moving the index 0 address into a register, calculating the offset from row and column (which requires multiplication... which is bad,) adding the values together, then grabbing the value from RAM, where the entire function above will take place in the registers without any adding or multiplying.
 
  • Informative
Likes   Reactions: Klystron

Similar threads

  • · Replies 16 ·
Replies
16
Views
5K
  • · Replies 28 ·
Replies
28
Views
4K
  • · Replies 5 ·
Replies
5
Views
2K
  • · Replies 17 ·
Replies
17
Views
3K
Replies
1
Views
2K
  • · Replies 3 ·
Replies
3
Views
3K
  • · Replies 4 ·
Replies
4
Views
3K
  • · Replies 20 ·
Replies
20
Views
5K
  • · Replies 49 ·
2
Replies
49
Views
12K
  • · Replies 5 ·
Replies
5
Views
6K