Use std::upper_bound. Using the standard algorithms is often the fastest and easiest way. std::upper_bound uses binary search, so is faster than a manual linear for loop as presented by econjack. Since they are part of the C++ Standard Library, they are well-tested and known to be correct.
Most importantly, it is much more readable than a raw loop: any C++ programmer can immediately tell what the upper_bound line is doing, interpreting 10 lines of for-loop code takes a lot longer to read.
The iterator syntax takes some getting used to, and has been improved in C++20 (not available on Arduino yet), but you can think of std::upper_bound(std::begin(Y), std::end(Y), X) as: search from the beginning to the end of the array for X.
An iterator such as the result variable is just a variable that points to an element in an array or other data structure. To get the value of the element that the iterator points to, you use an asterisk: *result.
[color=#5e6d03]#include[/color] [color=#434f54]<[/color][b][color=#d35400]Arduino_Helpers[/color][/b][color=#434f54].[/color][color=#000000]h[/color][color=#434f54]>[/color]
[color=#5e6d03]#include[/color] [color=#434f54]<[/color][b][color=#d35400]AH[/color][/b][color=#434f54]/[/color][color=#000000]STL[/color][color=#434f54]/[/color][color=#000000]algorithm[/color][color=#434f54]>[/color] [color=#434f54]// std::sort, std::upper_bound[/color]
[color=#5e6d03]#include[/color] [color=#434f54]<[/color][b][color=#d35400]AH[/color][/b][color=#434f54]/[/color][color=#000000]STL[/color][color=#434f54]/[/color][b][color=#d35400]iterator[/color][/b][color=#434f54]>[/color] [color=#434f54]// std::begin, std::end[/color]
[color=#00979c]void[/color] [color=#5e6d03]setup[/color][color=#000000]([/color][color=#000000])[/color] [color=#000000]{[/color]
[b][color=#d35400]Serial[/color][/b][color=#434f54].[/color][color=#d35400]begin[/color][color=#000000]([/color][color=#000000]115200[/color][color=#000000])[/color][color=#000000];[/color]
[color=#00979c]float[/color] [color=#000000]Y[/color][color=#000000][[/color][color=#000000]8[/color][color=#000000]][/color] [color=#434f54]=[/color] [color=#000000]{[/color][color=#000000]0[/color][color=#434f54],[/color][color=#000000]10[/color][color=#434f54],[/color][color=#000000]20[/color][color=#434f54],[/color][color=#000000]30[/color][color=#434f54],[/color][color=#000000]40[/color][color=#434f54],[/color][color=#000000]55[/color][color=#434f54],[/color][color=#000000]60[/color][color=#434f54],[/color][color=#000000]70[/color][color=#000000]}[/color][color=#000000];[/color]
[color=#00979c]float[/color] [color=#000000]X[/color] [color=#434f54]=[/color] [color=#000000]46[/color][color=#000000];[/color]
[color=#434f54]// Ensure all elements are sorted:[/color]
[color=#000000]std[/color][color=#434f54]:[/color][color=#434f54]:[/color][color=#000000]sort[/color][color=#000000]([/color][color=#000000]std[/color][color=#434f54]:[/color][color=#434f54]:[/color][color=#d35400]begin[/color][color=#000000]([/color][color=#000000]Y[/color][color=#000000])[/color][color=#434f54],[/color] [color=#000000]std[/color][color=#434f54]:[/color][color=#434f54]:[/color][color=#d35400]end[/color][color=#000000]([/color][color=#000000]Y[/color][color=#000000])[/color][color=#000000])[/color][color=#000000];[/color]
[color=#434f54]// Find the first element that's larger than X, and subtract one[/color]
[color=#434f54]// to get the one before it (result is an iterator to the element):[/color]
[color=#00979c]auto[/color] [color=#000000]result[/color] [color=#434f54]=[/color] [color=#000000]std[/color][color=#434f54]:[/color][color=#434f54]:[/color][color=#000000]upper_bound[/color][color=#000000]([/color][color=#000000]std[/color][color=#434f54]:[/color][color=#434f54]:[/color][color=#d35400]begin[/color][color=#000000]([/color][color=#000000]Y[/color][color=#000000])[/color][color=#434f54],[/color] [color=#000000]std[/color][color=#434f54]:[/color][color=#434f54]:[/color][color=#d35400]end[/color][color=#000000]([/color][color=#000000]Y[/color][color=#000000])[/color][color=#434f54],[/color] [color=#000000]X[/color][color=#000000])[/color] [color=#434f54]-[/color] [color=#000000]1[/color][color=#000000];[/color]
[color=#00979c]auto[/color] [color=#000000]index[/color] [color=#434f54]=[/color] [color=#000000]result[/color] [color=#434f54]-[/color] [color=#000000]std[/color][color=#434f54]:[/color][color=#434f54]:[/color][color=#d35400]begin[/color][color=#000000]([/color][color=#000000]Y[/color][color=#000000])[/color][color=#000000];[/color]
[color=#5e6d03]if[/color] [color=#000000]([/color][color=#000000]index[/color] [color=#434f54]<[/color] [color=#000000]0[/color][color=#000000])[/color] [color=#000000]{[/color]
[b][color=#d35400]Serial[/color][/b][color=#434f54].[/color][color=#d35400]println[/color][color=#000000]([/color][color=#005c5f]"Not found"[/color][color=#000000])[/color][color=#000000];[/color]
[color=#000000]}[/color] [color=#5e6d03]else[/color] [color=#000000]{[/color]
[b][color=#d35400]Serial[/color][/b][color=#434f54].[/color][color=#d35400]println[/color][color=#000000]([/color][color=#000000]index[/color][color=#000000])[/color][color=#000000];[/color]
[b][color=#d35400]Serial[/color][/b][color=#434f54].[/color][color=#d35400]println[/color][color=#000000]([/color][color=#434f54]*[/color][color=#000000]result[/color][color=#000000])[/color][color=#000000];[/color]
[color=#000000]}[/color]
[color=#000000]}[/color]
[color=#00979c]void[/color] [color=#5e6d03]loop[/color][color=#000000]([/color][color=#000000])[/color] [color=#000000]{[/color][color=#000000]}[/color]
If you're using an ARM-based or ESP-based Arduino, simply use #include and #include , they are already installed.
If you're using an AVR-based Arduino, you'll have to install them through the Arduino Helpers library or the ArduinoSTL library.
// put your setup code here, to run once:
float Y[8] = {0, 10, 20, 30, 40, 55, 60, 70};
float newDifference, oldDifference;
int index;
float target = 46.0;
Serial.begin(9600);
while (!Serial)
;
newDifference = fabs(Y[0] - target);
for (int i = 0; i < 8; i++) {
newDifference = fabs(Y[i] - target);
if (newDifference < oldDifference) {
oldDifference = newDifference;
index = i;
}
}
Serial.print("closest = ");
Serial.println(Y[index]);
}
void loop() {
}
oldDifference is used before it's initialized, and using fabs implies that it doesn't search for the closest number less than the target.
Which kind of proves my point: all unnecessary algorithms you implement yourself are prone to errors, use the standard library algorithms instead, they're there for a reason.
PieterP:
Which kind of proves my point: all unnecessary algorithms you implement yourself are prone to errors, use the standard library algorithms instead, they're there for a reason.
Whilst I agree to a certain extent, for someone starting out (and someone who is uncertain about correct use of the caps lock key), learning the language and the libraries is just overload, and likely to be off-putting.
Better, IMO, is to learn the outline of the necessary techniques first.
i have an array of numbers and i would like to know, what is the closest position that is equal or smaller than "x"
Start with a for loop, and probably a break.
Since the array is always in an ascending order its pretty simple if you test the values from large to small.
void setup() {
Serial.begin(115200);
float x = 46;
float Y[8] = {0, 10, 20, 30, 40, 55, 60, 70};
for (byte i = 7; i >= 0 ; i--)//check larger values first
{
if (Y[i] <= x)
{
Serial.print("First array value less than x is ");
Serial.println(Y[i]);
break; //exit test loop
}
}
}
void loop() {}
TheMemberFormerlyKnownAsAWOL:
Whilst I agree to a certain extent, for someone starting out (and someone who is uncertain about correct use of the caps lock key), learning the language and the libraries is just overload, and likely to be off-putting.
Better, IMO, is to learn the outline of the necessary techniques first.
True, there's nothing wrong with implementing some basic algorithms to learn about for-loops and general programming techniques.
The problem is that many people keep doing that when they start writing serious code. They need to find an element in a sorted array, so they quickly implement their own binary search, for instance. It doesn't help that over half of the google results for "c++ binary search" are manual implementations.
Just looking at this thread alone, it's clear that even experienced programmers make mistakes in relatively simple code.
That's why I think it's a good idea to point to the right algorithms in forum threads like these.
Learning the necessary techniques is definitely important, I fully agree with you there, but I don't think an online forum is the right tool for that, you'll learn much more by following a more structured guide like a book or a course/tutorial, doing the exercises that it comes with, etc.
Thank you very much for the information and sharing the librarys and the code , works perfectky
but i want to know if i can make also the inverse logic , i mean , to find the 2 next highest numbers
thanks and regards
You can use std::upper_bound again. It returns an iterator to the first element that's larger than X. If you want the next highest number, you add one to the iterator. In this case, you have to make sure not to go out of bounds on the array:
[color=#00979c]float[/color] [color=#000000]Y[/color][color=#000000][[/color][color=#000000]8[/color][color=#000000]][/color] [color=#434f54]=[/color] [color=#000000]{[/color][color=#000000]0[/color][color=#434f54],[/color][color=#000000]10[/color][color=#434f54],[/color][color=#000000]20[/color][color=#434f54],[/color][color=#000000]30[/color][color=#434f54],[/color][color=#000000]40[/color][color=#434f54],[/color][color=#000000]55[/color][color=#434f54],[/color][color=#000000]60[/color][color=#434f54],[/color][color=#000000]70[/color][color=#000000]}[/color][color=#000000];[/color]
[color=#00979c]float[/color] [color=#000000]X[/color] [color=#434f54]=[/color] [color=#000000]46[/color][color=#000000];[/color]
[color=#434f54]// Ensure all elements are sorted:[/color]
[color=#000000]std[/color][color=#434f54]:[/color][color=#434f54]:[/color][color=#000000]sort[/color][color=#000000]([/color][color=#000000]std[/color][color=#434f54]:[/color][color=#434f54]:[/color][color=#d35400]begin[/color][color=#000000]([/color][color=#000000]Y[/color][color=#000000])[/color][color=#434f54],[/color] [color=#000000]std[/color][color=#434f54]:[/color][color=#434f54]:[/color][color=#d35400]end[/color][color=#000000]([/color][color=#000000]Y[/color][color=#000000])[/color][color=#000000])[/color][color=#000000];[/color]
[color=#434f54]// Find the first element that's larger than X[/color]
[color=#00979c]auto[/color] [color=#000000]larger1[/color] [color=#434f54]=[/color] [color=#000000]std[/color][color=#434f54]:[/color][color=#434f54]:[/color][color=#000000]upper_bound[/color][color=#000000]([/color][color=#000000]std[/color][color=#434f54]:[/color][color=#434f54]:[/color][color=#d35400]begin[/color][color=#000000]([/color][color=#000000]Y[/color][color=#000000])[/color][color=#434f54],[/color] [color=#000000]std[/color][color=#434f54]:[/color][color=#434f54]:[/color][color=#d35400]end[/color][color=#000000]([/color][color=#000000]Y[/color][color=#000000])[/color][color=#434f54],[/color] [color=#000000]X[/color][color=#000000])[/color][color=#000000];[/color]
[color=#5e6d03]if[/color] [color=#000000]([/color][color=#000000]larger1[/color] [color=#434f54]<[/color] [color=#000000]std[/color][color=#434f54]:[/color][color=#434f54]:[/color][color=#d35400]end[/color][color=#000000]([/color][color=#000000]Y[/color][color=#000000])[/color][color=#000000])[/color] [color=#000000]{[/color] [color=#434f54]// don't go past the end of the array[/color]
[b][color=#d35400]Serial[/color][/b][color=#434f54].[/color][color=#d35400]println[/color][color=#000000]([/color][color=#434f54]*[/color][color=#000000]larger1[/color][color=#000000])[/color][color=#000000];[/color]
[color=#00979c]auto[/color] [color=#000000]larger2[/color] [color=#434f54]=[/color] [color=#000000]larger1[/color] [color=#434f54]+[/color] [color=#000000]1[/color][color=#000000];[/color]
[color=#5e6d03]if[/color] [color=#000000]([/color][color=#000000]larger2[/color] [color=#434f54]<[/color] [color=#000000]std[/color][color=#434f54]:[/color][color=#434f54]:[/color][color=#d35400]end[/color][color=#000000]([/color][color=#000000]Y[/color][color=#000000])[/color][color=#000000])[/color] [color=#000000]{[/color] [color=#434f54]// don't go past the end of the array[/color]
[b][color=#d35400]Serial[/color][/b][color=#434f54].[/color][color=#d35400]println[/color][color=#000000]([/color][color=#434f54]*[/color][color=#000000]larger2[/color][color=#000000])[/color][color=#000000];[/color]
[color=#000000]}[/color]
[color=#000000]}[/color] [color=#5e6d03]else[/color] [color=#000000]{[/color]
[b][color=#d35400]Serial[/color][/b][color=#434f54].[/color][color=#d35400]println[/color][color=#000000]([/color][color=#005c5f]"Not found"[/color][color=#000000])[/color][color=#000000];[/color]
[color=#000000]}[/color]