Using one index in two arrays

Firstly, if my code is awful, please be gentle, I'm very new lol. I'm trying to write a code where the user inputs a number between 8.0 and 12.0. Each value (8.0, 8.1, 8.2, 8.3, etc..) has two times associated with it. So, when the user inputs their number, I want the right associated time to print out.

The code I wrote works with most of the numbers. But for some numbers (e.g. 8.4), it doesn't print out anything and it loops back to the beginning. Any idea why?

Also, is there a better way to do this?

int user_choice;
float linespeed[] = {8.0, 8.1, 8.2, 8.3, 8.4, 8.5, 8.6, 8.7, 8.8, 8.9, 9.0, 9.1, 9.2, 9.3, 9.4, 9.5, 9.6, 9.7, 9.8, 9.9, 10.0, 10.1, 10.2, 10.3, 10.4, 10.5, 10.6, 10.7, 10.8, 10.9, 11.0, 11.1, 11.2, 11.3, 11.4, 11.5, 11.6, 11.7, 11.8, 11.9, 12.0};

String starttime[] = {"1:35", "1:36", "1:37", "1:38", "1:39", "1:39", "1:40", "1:41", "1:42", "1:43", "1:43", "1:44", "1:45", "1:45", "1:46", "1:47", "1:47", "1:48", "1:49", "1:49", "1:50", "1:51", "1:51", "1:52", "1:52", "1:53", "1:53", "1:54", "1:54", "1:55", "1:55", "1:56", "1:56", "1:57", "1:57", "1:58", "1:58", "1:59", "1:59", "2:00", "2:00"};

String stoptime[] = {"12:27", "12:28", "12:30", "12:31", "12:32", "12:33", "12:35", "12:36", "12:37", "12:38", "12:39", "12:40", "12:42", "12:43", "12:44", "12:45", "12:46", "12:47", "12:48", "12:48", "12:49", "12:50", "12:51", "12:52", "12:53", "12:54", "12:55", "12:55", "12:56", "12:57", "12:58", "12:58", "12:59", "1:00", "1:01", "1:01", "1:02", "1:03", "1:03", "1:04", "1:04"};

float user_num;



void setup() {
  
Serial.begin(9600);
}

void loop() {
 
Serial.println("Enter 1 for color change times, enter 2 for times to stop hanging: ");
while (!Serial.available()){
  
}
user_choice = Serial.parseInt();

if (user_choice == 1){
  Serial.println("Enter the fastest RED line speed (8.0 - 12.0): ");
  while (!Serial.available()){
    
  }
user_num = Serial.parseFloat();
  for(int i = 0; i < 41; i++){
    if (user_num == linespeed[i]){
     Serial.println(starttime[i]);
     
    }
  }

  
}

if (user_choice == 2){
  Serial.println("Enter the slowest RED line speed (8.0 - 12.0): ");
  while (!Serial.available()){
}
user_num = Serial.parseFloat();
for(int j = 0; j < 41; j++){
    if (user_num == linespeed[j]){
      Serial.println(stoptime[j]);
    }
 
}
}
}

Don't ever assume that two float variables are exactly the same.

1 Like

Ah, I looked up why and I did not know that. So, if I can't directly compare them, and all my "line speed" values are 0.1 apart, could I do something like "if the absolute value of the difference between linespeed[i] and user_num is less than 0.09, assume they're equal"?

If the numbers only have one digit after the comma, multiply by 10; for two digits, multiply by 100.

I would multiply by 10 and add 0.5 before truncating to an integer to get a value between 80 and 120.

int index = (user_num * 10) + 0.5;

Then subtract 80 to get an index into the answer arrays.
Serial.println(starttime[index-80]);

Both @johnwasser and @johnwasser make a recommendation that the entire matter be taken out of floating point cakulations, I agree. An effective and time honest approach.

But I write to say that yes! Exactly as you outline would be how to do it if you want to stay with you original plan.

It may not be needed in this circumstance, but good to know.

For ease if you ever do, write a function to do a “fuzzy equality” check on its arguments. The fuzz factor is up to you. As you may have learned, floating point numbers can be quite nearly equal, so a bit of blurring so to speak will get you there.

a7

Does John have a split personality? :smiley:

We don't think so, but we'll discuss it and get back to you.

4 Likes

:rofl: :rofl: :rofl:

then these values are not only 3 variables, but a data structure. Define a struct and make one array with your structure!

struct Data {
  float linespeed; // think about if you really need a float, maybe a unsigned integer value multiplied by 10 is enouh
 String startime;  // think about an unsigned integer holding "135" as example
String stoptime;
};

Data data[]{
{8.0, "1:35", "12:27"},
{8.1, "1:36", "12:28"},
// and so on
};

example to access the values:

data[0].linespeed = 8.23;

learn more about it with c++ structure

Haha no but @alto777 does have fat fingers and often fails to look at what he types…

a7

"If the numbers only have one digit after the comma, multiply by 10; for two digits, multiply by 100."

I tried this and it seems to be working. After the user inputs "user_num" I have:
"int num = user_num * 10;"

And then in the for loop I have:
"if(num == (starttime[i] * 10){"

I get the correct times for the line speed values and they all print out now

FWIW and amazed I am to have found it

# define FUZZ	1.0e-06

int fuzzeq(farg1, farg2)
double farg1, farg2;
{
	double temp;
 
	temp = farg1 - farg2;
	return (FUZZ > fabs(temp));
}

You can tell by the old style declaration that it's wicked old code.

a7

2 Likes