# Finding max and min numbers in the stack

## Recommended Posts

Hi everybody,Using XML and having a series of numbers in the stack such as8 3 2 5 1 4 9 , how could I find the maximum and minimum numbers?In fact, I want to find the minimum number, then the next minimum, and so on and basically reshuffle the numbers into1 2 3 4 5 8 9Also, for completeness, I may have duplicated numbers like,7 4 2 8 4 6 2 9, so this would be reshuffled to,2 2 4 4 6 7 8 9Many thanks, nick

##### Share on other sites
 Help AVSIM continue to serve you!Please donate today!

Nick,The first question, finding the max and min of the series is an easy job:-):8 3 2 5 1 4 9 min min min min min min to obtain the lowest value (1)8 3 2 5 1 4 9 max max max max max max to obtain the highest value (9)The second option is a not so easy job. To help you find the (best) solution, I would need more info, like:1-Is that serie of numbers fixed? ie do you know how many are originally placed on the stack? 2-Do you need the reshuffled stack in a form of "1 2 3 4 5 5 n case"? or directly as a line of values each to assign to a Lvar or s register?TomEDIT: The solution seems to be easy as well. But I'll wait for your response to make it :-)

##### Share on other sites

Hi Tom, how's it going?I am making a TCAS in XML and it's going well. I have a dll that produces various L:Variables for each of 96 possible aircraft. Each aircraft has L:variables for things like its range, VS, bearing, etc. I have 3 sections per aircraft to display symbols and aircraft information on the gauge. The gauge works well, but to cater for all 96 aircraft I would have a lot of code. Also, let's say there are 10 active aircraft, the highest slot number could be 30, so there are empty slots (zero information) until all required information is found. Also, I only need to display information on the eight closest aircraft. What I want to do is scan all 96 aircraft for their range, take the closest eight, and set the eight aircraft's other L:variables to a generic set of L:Variables that would be used in eight sections for displaying on the gauge.I hope I have explained enough for you,>1-Is that serie of numbers fixed? ie do you know how many are originally placed on the stack?The situation is dynamic. Aircraft come and go,so the total number varies. >2-Do you need the reshuffled stack in a form of "1 2 3 4 5 5 n case"? or directly as a line of values each to assign to a Lvar or s register?Like I said, I need to find the closest, and then assisg it's conditional L:Variables to a generic set, then find the next closest, etc.I am having some initial success with lines like,%((L:mem,enum) ++ d (>L:mem,enum) 7 > if{ 0 (>L:mem,enum) 50 (>L:lowest_00,enum) } 34 52 22 14 8 27 6 24 8 (L:mem,enum) case s0 (L:lowest_00,enum) < if{ l0 (>L:lowest_00,enum) } (L:lowest_00,enum) )%!d!but this looks long-winded to me and I'm sure there must be more efficient methods using stack manipulation.BTW, the L:Variables from the dll are in the format,L:xml_tcas_range_XXL:xml_tcas_alt_XX, etcwhere XX is 00 to 95cheers,nick

##### Share on other sites

>Hi Tom, how's it going?Hi Nick, going great!. Another boring evening at the office until you threw some food to play with :-)>Like I said, I need to find the closest, and then assisg it's conditional L:Variables to a generic set, then find the next closest, etc.So for example, you test L:xml_tcas_range_45 and find it to be the closest; therefore take L:xml_tcas_alt_45 and assign this value to another LVar, and so on??It seems you need to test each of the 96 variables, discarding those that return 0 in range (means no aircraft is actually present)?Am I assuming right?Tom

##### Share on other sites

Hi Tom, your understanding is spot on correct. I do have an L:Variable that tells you the highest active aircraft slot, so that if after aircraft 50, if all the slots above this up to 96 (00 to 95)have no aircraft, it gives the value 50. Not really sure if this is of any use.cheers,nick

##### Share on other sites

Further. What might help is that only the integer values of range are important, and the mileage values do not change that relatively quickly, so the gauge running at 18 cycles per second should be able to find the eight closest aircraft and set-up a set of eight generic L:Variables before any of the range values change.cheers,nick

##### Share on other sites

Nick,I think that in every way your solution will mean quite a number of code lines, for sure. I'll have little time today to be able to figure out something, but weekend is arriving...:-)BTW, this is the simplest solution I've found to your second "raw" question:>8 3 2 5 1 4 9 , how could I find the maximum and minimum numbers?>In fact, I want to find the minimum number, then the next minimum, >and so on and basically reshuffle the numbers into>1 2 3 4 5 8 9>Also, for completeness, I may have duplicated numbers like,>7 4 2 8 4 6 2 9, so this would be reshuffled to,<2 2 4 4 6 7 8 9Suppose you have 4 lVars and want to order them from min to max:This is the macrol1 l2 > if{ l2 l1 1 sp30 } els{ l1 l2 } d l3 > if{ l3 r 1 sp30 } els{ l3 } d l4 > if{ l4 r 1 sp30 } els{ l4 }sp4 sp3 sp2 sp1And, in an or section(LVarA) sp1(lVarB) sp2(LVarC) sp3(LVarD) sp40 sp30:0@Sortl30 1 == if{ 0 sp30 g0 }l1 (>L:Var_00,number)l2 (>L:Var_01,number)l3 (>L:Var_02,number)l4 (>L:Var_03,number)The resultant stack is correlatively ordered from min to max. Duplicated values are handled as well.Notice that you can add as many LVars to sort as wished (up to 49 if using registers), with very little changes to the code. Tom

##### Share on other sites

Thanks Tom, I shall read and give a test. Your help is much appreciated. It's an interesting project. Taking on the simple stuff is boring :-) cheers,nick

##### Share on other sites

Hi again Tom. This is interesting. If the code is used in the order you have posted, registers like l0, l1, etc are presented first (in the macro) before being set by s0, s1, etc. I have found in the past that doing this resulted in zero. It's as though the registers are reset to zero with every gauge cycle, and so the S0, S1, etc syntax has to come in front. Can you enlighten me a little more.1) Are registers set to zero with each gauge cycle?2) Why would this work even though l0, l1, etc are read first?thanks again,nickEdit. Put brain into gear. The macro is used AFTER the registers are set with s0 etc. That answers Q2. Would you be kind enough to answer Q1 please.

##### Share on other sites

Hi Tom, can the code be modified to ignore inputs that are zero?That is, if(L:xml_tcas_range_00,nmiles) flr equals zero(L:xml_tcas_range_01,nmiles) flr equals value(L:xml_tcas_range_02,nmiles) flr equals zero(L:xml_tcas_range_03,nmiles) flr equals value(L:xml_tcas_range_04,nmiles) flr equals value(L:xml_tcas_range_05,nmiles) flr equals value(L:xml_tcas_range_06,nmiles) flr equals zero(L:xml_tcas_range_07,nmiles) flr equals valueso that the closest with values can be shuffled into the first X positions.cheers,nick

##### Share on other sites

Nick,>1) Are registers set to zero with each gauge cycle?Yes. And also whenever a "c" operator is placed on the stack.>Edit. Put brain into gear. The macro is used AFTER the registers are set with s0 etc. That answers Q2. Yes, it does answer Q2. Remember macros' structures must be placed in the gauge BEFORE they are called, otherwise AFAIT they are directly ignored (the compiler can't solve the calling name because cannot find it in the preceding code)Tom

##### Share on other sites

>Hi Tom, can the code be modified to ignore inputs that are>zero?>That is, if>>(L:xml_tcas_range_00,nmiles) flr equals zero>(L:xml_tcas_range_01,nmiles) flr equals value>(L:xml_tcas_range_02,nmiles) flr equals zero>(L:xml_tcas_range_03,nmiles) flr equals value>(L:xml_tcas_range_04,nmiles) flr equals value>(L:xml_tcas_range_05,nmiles) flr equals value>(L:xml_tcas_range_06,nmiles) flr equals zero>(L:xml_tcas_range_07,nmiles) flr equals value>>so that the closest with values can be shuffled into the first>X positions.>cheers,>nickI've almost finished the example code to make what you want in a simple way (IMHO). Going to post it here as soon as possible. Regards,Tom

##### Share on other sites

Hi Tom, did you have any luck?cheers,nick

##### Share on other sites

Nick,The first part (sorting "range" var ignoring empty slots) is done.But I have problems to get the related 3 extra vars (bearing,VS,etc)already sorted.FS crashes in panels.dll because I'm trying to use 3rd level recursive macro calls. Guess I'll have to change the routine.Please wait for my news.Tom

##### Share on other sites

HOW TO ORDER LVAR VALUES FROM MIN TO MAX - AN EXAMPLE===================================================== In this example we have a set of 96 data positions, each consisting of a group of Local Vars that receive different values from a custom DLL in an automatic way, being refreshed by FS current gauge's cycle.Variables recalled from the dll are in the format L:xml_tcas_range_XXL:xml_tcas_alt_XX, etcwhere XX is 00 to 95In this case we are going to consider 4:(L:xml_tcas_range_XX,nmiles)(L:xml_tcas_alt_XX,feet)(L:xml_tcas_VS_XX,feet per minute) (L:xml_tcas_bearing_XX,degrees) but others may be added as needed.The main routine consist of a sort of the 96 (L:xml_tcas_range_XX,nmiles) values, from min (00) to max (96), discarding those who return 0 nmiles. Then only the eight first sorted (L:xml_tcas_range_XX,nmiles) values are considered, from min to max, and assigned to other Local variables ordered from 00 to 07For example, (L:xml_tcas_range_X0,nmiles) min (position 0) value is assigned to (L:TcasRange_00,nmiles)(L:xml_tcas_range_X7,nmiles) max (position 7) value is assigned to (L:TcasRange_07,nmiles)(L:xml_tcas_alt_X0,feet) min (position 0) value is assigned to (L:TcasAlt_00,feet)(L:xml_tcas_alt_X7,feet) min (position 7) value is assigned to (L:TcasAlt_07,feet)and so onThis is the best code I've figured out. It is balanced between stack's manipulation efficiency and ease of readness, taking into account there were some XML limitations that had to be dealt with, like stack's max 30 number of elements, a max number of parameters to be passed in a macro call, a max number of nested macros, amongst others.It has been tested and works perfect, at least for 4 different lVars. I guess should work fine with more LVars as well.Here you'll find some interesting structures, like multiple parameter passings in macros, extensive use of "s" registers for speed, nested macros, nested loops ("goto" or "g"), etc. I haven't found any FPS impact for using this example in a gauge.Tom-------------------------------------------------------------------The code is listed in the order it should be placed on the gaugeetc.. (L:TcasAlt_@1,feet) sp25 (L:TcasAlt_@2,feet) sp26 l25 (>L:TcasAlt_@2,feet) l26 (>L:TcasAlt_@1,feet) (L:TcasBearing_@1,degrees) sp25 (L:TcasBearing_@2,degrees) sp26 l25 (>L:TcasBearing_@2,degrees) l26 (>L:TcasBearing_@1,degrees) (L:TcasVS_@1,feet per minute) sp25 (L:TcasVS_@2,feet per minute) sp26 l25 (>L:TcasVS_@2,feet per minute) l26 (>L:TcasVS_@1,feet per minute) l31 if{ l15 l14 < if{ l14 l15 1 sp30 @R1(14,15) } els{ l5 l14 } d l13 < if{ l13 r 1 sp30 @R1(13,14) } els{ l13 } d l12 < if{ l12 r 1 sp30 @R1(12,13) } els{ l12 } d l11 < if{ l11 r 1 sp30 @R1(11,12) } els{ l11 } d l10 < if{ l10 r 1 sp30 @R1(10,11) } els{ l10 } d l9 < if{ l9 r 1 sp30 @R1(09,10) } els{ l9 } d l8 < if{ l8 r 1 sp30 @R1(08,09) } els{ l8 } d l7 < if{ l7 r 1 sp30 @R1(07,08) } els{ l7 } d l6 < if{ l6 r 1 sp30 @R1(06,07) } els{ l6 } d } els{ l7 l6 < if{ l6 l7 1 sp30 @R1(06,07) } els{ l7 l6 } d } l5 < if{ l5 r 1 sp30 @R1(05,06)} els{ l5 } d l4 < if{ l4 r 1 sp30 @R1(04,05) } els{ l4 } d l3 < if{ l3 r 1 sp30 @R1(03,04) } els{ l3 } d l2 < if{ l2 r 1 sp30 @R1(02,03) } els{ l2 } d l1 < if{ l1 r 1 sp30 @R1(01,02) } els{ l1 } d l0 < if{ l0 r 1 sp30 @R1(00,01) } els{ l0 } sp0 sp1 sp2 sp3 sp4 sp5 sp6 sp7 l31 if{ sp8 sp9 sp10 sp11 sp12 sp13 sp14 sp15 } d 0 == if{ p 9999 } (L:xml_tcas_range_@1,nmiles) @Lt0 sp0 (L:xml_tcas_range_@2,nmiles) @Lt0 sp1 (L:xml_tcas_range_@3,nmiles) @Lt0 sp2 (L:xml_tcas_range_@4,nmiles) @Lt0 sp3 (L:xml_tcas_range_@5,nmiles) @Lt0 sp4 (L:xml_tcas_range_@6,nmiles) @Lt0 sp5 (L:xml_tcas_range_@7,nmiles) @Lt0 sp6 (L:xml_tcas_range_@8,nmiles) @Lt0 sp7 (L:xml_tcas_alt_@1,feet) (>L:TcasAlt_00,feet) (L:xml_tcas_alt_@2,feet) (>L:TcasAlt_01,feet) (L:xml_tcas_alt_@3,feet) (>L:TcasAlt_02,feet) (L:xml_tcas_alt_@4,feet) (>L:TcasAlt_03,feet) (L:xml_tcas_alt_@5,feet) (>L:TcasAlt_04,feet) (L:xml_tcas_alt_@6,feet) (>L:TcasAlt_05,feet) (L:xml_tcas_alt_@7,feet) (>L:TcasAlt_06,feet) (L:xml_tcas_alt_@8,feet) (>L:TcasAlt_07,feet) (L:xml_tcas_bearing_@1,degrees) (>L:TcasBearing_00,degrees) (L:xml_tcas_bearing_@2,degrees) (>L:TcasBearing_01,degrees) (L:xml_tcas_bearing_@3,degrees) (>L:TcasBearing_02,degrees) (L:xml_tcas_bearing_@4,degrees) (>L:TcasBearing_03,degrees) (L:xml_tcas_bearing_@5,degrees) (>L:TcasBearing_04,degrees) (L:xml_tcas_bearing_@6,degrees) (>L:TcasBearing_05,degrees) (L:xml_tcas_bearing_@7,degrees) (>L:TcasBearing_06,degrees) (L:xml_tcas_bearing_@8,degrees) (>L:TcasBearing_07,degrees) (L:xml_tcas_VS_@1,feet per minute) (>L:TcasVS_00,feet per minute) (L:xml_tcas_VS_@2,feet per minute) (>L:TcasVS_01,feet per minute) (L:xml_tcas_VS_@3,feet per minute) (>L:TcasVS_02,feet per minute) (L:xml_tcas_VS_@4,feet per minute) (>L:TcasVS_03,feet per minute) (L:xml_tcas_VS_@5,feet per minute) (>L:TcasVS_04,feet per minute) (L:xml_tcas_VS_@6,feet per minute) (>L:TcasVS_05,feet per minute) (L:xml_tcas_VS_@7,feet per minute) (>L:TcasVS_06,feet per minute) (L:xml_tcas_VS_@8,feet per minute) (>L:TcasVS_07,feet per minute) (L:xml_tcas_range_@1,nmiles) @Lt0 sp8 (L:xml_tcas_range_@2,nmiles) @Lt0 sp9 (L:xml_tcas_range_@3,nmiles) @Lt0 sp10 (L:xml_tcas_range_@4,nmiles) @Lt0 sp11 (L:xml_tcas_range_@5,nmiles) @Lt0 sp12 (L:xml_tcas_range_@6,nmiles) @Lt0 sp13 (L:xml_tcas_range_@7,nmiles) @Lt0 sp14 (L:xml_tcas_range_@8,nmiles) @Lt0 sp15 (L:xml_tcas_alt_@1,feet) (>L:TcasAlt_08,feet) (L:xml_tcas_alt_@2,feet) (>L:TcasAlt_09,feet) (L:xml_tcas_alt_@3,feet) (>L:TcasAlt_10,feet) (L:xml_tcas_alt_@4,feet) (>L:TcasAlt_11,feet) (L:xml_tcas_alt_@5,feet) (>L:TcasAlt_12,feet) (L:xml_tcas_alt_@6,feet) (>L:TcasAlt_13,feet) (L:xml_tcas_alt_@7,feet) (>L:TcasAlt_14,feet) (L:xml_tcas_alt_@8,feet) (>L:TcasAlt_15,feet) (L:xml_tcas_bearing_@1,degrees) (>L:TcasBearing_08,degrees) (L:xml_tcas_bearing_@2,degrees) (>L:TcasBearing_09,degrees) (L:xml_tcas_bearing_@3,degrees) (>L:TcasBearing_10,degrees) (L:xml_tcas_bearing_@4,degrees) (>L:TcasBearing_11,degrees) (L:xml_tcas_bearing_@5,degrees) (>L:TcasBearing_12,degrees) (L:xml_tcas_bearing_@6,degrees) (>L:TcasBearing_13,degrees) (L:xml_tcas_bearing_@7,degrees) (>L:TcasBearing_14,degrees) (L:xml_tcas_bearing_@8,degrees) (>L:TcasBearing_15,degrees) (L:xml_tcas_VS_@1,feet per minute) (>L:TcasVS_08,feet per minute) (L:xml_tcas_VS_@2,feet per minute) (>L:TcasVS_09,feet per minute) (L:xml_tcas_VS_@3,feet per minute) (>L:TcasVS_10,feet per minute) (L:xml_tcas_VS_@4,feet per minute) (>L:TcasVS_11,feet per minute) (L:xml_tcas_VS_@5,feet per minute) (>L:TcasVS_12,feet per minute) (L:xml_tcas_VS_@6,feet per minute) (>L:TcasVS_13,feet per minute) (L:xml_tcas_VS_@7,feet per minute) (>L:TcasVS_14,feet per minute) (L:xml_tcas_VS_@8,feet per minute) (>L:TcasVS_15,feet per minute) l41 1 == if{ @Assign2(08,09,10,11,12,13,14,15) } l41 2 == if{ @Assign2(16,17,18,19,20,21,22,23) } l41 3 == if{ @Assign2(24,25,26,27,28,29,30,31) } l41 4 == if{ @Assign2(32,33,34,35,36,37,38,39) } l41 5 == if{ @Assign2(40,41,42,43,44,45,46,47) } l41 6 == if{ @Assign2(48,49,50,51,52,53,54,55) } l41 7 == if{ @Assign2(56,57,58,59,60,61,62,63) } l41 8 == if{ @Assign2(64,65,66,67,68,69,70,71) } l41 9 == if{ @Assign2(72,73,74,75,76,77,78,79) } l41 10 == if{ @Assign2(80,81,82,83,84,85,86,87) } l41 11 == if{ @Assign2(88,89,90,91,92,93,94,95) } @Assign1(00,01,02,03,04,05,06,07,08) 0 sp40 :0 @Sort l40 if{ 0 sp40 g0 } 1 sp41 :1 @Repeat 0 sp40 1 sp31 :2 @Sort l40 if{ 0 sp40 g2 } l41 ++ s41 12 < if{ g1 } l0 (>L:TcasRange_00,nmiles) l1 (>L:TcasRange_01,nmiles) l2 (>L:TcasRange_02,nmiles) l3 (>L:TcasRange_03,nmiles) l4 (>L:TcasRange_04,nmiles) l5 (>L:TcasRange_05,nmiles) l6 (>L:TcasRange_06,nmiles) l7 (>L:TcasRange_07,nmiles)...rest of the code

##### Share on other sites

WOW, you are the Macro King Tom. Many thanks for the code. I'll run off now and give this a try. Many, many thanks for your help with this.cheers for now,nick

##### Share on other sites

Hi Tom, having great fun with this.Now, L:Variables are interactive between different gauges. Is this the same with macros. Can you set up a macro in one gauge, and then use the @macro name in another?I'm going through your code at the moment. You say it filters out those ranges that are zero. I'm attempting to find out how it does this. This will hopefully give me an understanding how I can then filter out aircraft that are more than plus or minus 9900 feet away from my aircraft, that is, their relative altitude to my aircraft is greater than plus or minus 9900 feet. Should keep me off the streets for a while.cheers,nick

##### Share on other sites

""Hi Tom, having great fun with this.""Hey Nick, I plenty understand you cause I HAD great fun coding the stuff!!:-)""Can you set up a macro in onegauge, and then use the @macro name in another?""Unfortunately no. But you can copy and paste the code, and that's a great advantage per se if you see it optimistically.Remember that macros are literal replacement of code; also parameters passed to macros replace their corresponding @n tags literally. ""You say it filters out those ranges that are zero. I'm attempting to find out how it does this.""Well, there is a bit of cheating here. If you take a look at this macro: d 0 == if{ p 9999 }in fact what the code does is assign 9999 to those lvars (or "s" positions) that are zero. All these will be "pushed" to the last positions. It's simpler and faster than other alternatives that I evaluated. What you have to do is, in case you find a "Lvar_nmiles" in a position lower than 08 that reads 9999, just discard it and its related ones. I forgot to mention this, sorry."This will hopefully give me an understanding howI can then filter out aircraft that are more than plus orminus 9900 feet away from my aircraft, that is, theirrelative altitude to my aircraft is greater than plus orminus 9900 feet"Once you understand how the code manages the interaction between stack variables and operators inside the macros, you'll find very easy to create any kind of filtering conditions between the set of variables. Take your time, I guess that's part of the fun :-)Let me know of your progress.Regards,Tom

##### Share on other sites

Thank you Tom, you are very helpful. Now back to some headscratching.cheers for now,nick

## Create an account

Register a new account

• Tom Allensworth,
Founder of AVSIM Online

• ### Hot Spots

• Flight Simulation's Premier Resource!

AVSIM is a free service to the flight simulation community. AVSIM is staffed completely by volunteers and all funds donated to AVSIM go directly back to supporting the community. Your donation here helps to pay our bandwidth costs, emergency funding, and other general costs that crop up from time to time. Thank you for your support!