jydepower Posted June 16, 2015 Report Posted June 16, 2015 Hallo. Im trying to make a function. Im not sure what aproach to take. I have an array of int [1..15] with mixed numbers. What i need to be able to do, is to find the element that is closest and LT a value(search number). Lets say the array is [1..5] instead for easy example and the values are 4000, 2000, 3500, 6000, 1000. My search number is = 3000 My result would be element 2 = 2000. My approach to find this was to use the SORT function. Then i could start a loop comparation from the high end, and the first value that was under was the correct on. My problem is. When using the SORT function i loose my array index order which i need onwards. So i my idea was to convert to a DINT and ADD a "tracking number" in the upper half of the DINT. Do the SORT and then look at the sencond half of all the DINT's when doing the loop. Something like this 10000004000, 20000002000, 30000003500, 40000006000, 50000001000 (i know the numbers arent correct). In case this is a good aproach. I need to know how to ADD the two INTs into a DINT. I cant find a function that does it. Does this make sense? is it even possible? what way would you go?
Nightfly Posted June 16, 2015 Report Posted June 16, 2015 (edited) I would do something like the following... subscript := 0; requiredMatch := 3000; smallestDiff := 32767; FOR X:= 1 TO 15 DO diff := requiredMatch - myArray[X]; (* get the difference between the search item and the item in the array *) IF diff < 0 THEN (* if the difference is negative then make it positive *) diff := diff * -1; END_IF; IF diff <= smallestDiff THEN (* if it is the smallest difference then record where it is in the array *) smallestDiff := diff; (* if there are two items with the same difference to the one you are comparing *) subscript := X; (* then using < will find the first match using <= the last one *) END_IF; END_FOR; myArray[subscript] (* the nearest match *) but I'm sure somebody could do it more elegantly! Regards Edited June 16, 2015 by Nightfly
panic mode Posted June 17, 2015 Report Posted June 17, 2015 this is definitely doable. no need to shuffle elements or sort them, single pass will do (and you want that on PLC for fast execution times). I don't have access to Mitsi software at the moment (never had to IEC version) so here is my attempt (pseudo code): LT_target:=3000; (* target limit, need LT this value *)LT_value:= -32768;(* initialize current "best LT value" *)LT_index := -1; (* assume result does not exist *)FOR X:=0 to 15 DO IF ((myArray[x]<LT_target) AND (myArray[x]>LT_value)) THEN (* better match found so... *) LT_value:=myArray[x]; (* ...record value and index *) LT_index:=X; END_IF;END_FOR;(* your result is in "LT_index", if negative, no value is found *)
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now