Monday, November 8, 2010

Bitwise Comparison

Say you want to have a routine in QUEST SCL that may have to do some things and not others, or vice versa. One way you can specify what sections of code to do is have a series of "flag" that tells the routine what to do and not do. Each flag controls one aspect of the code.

One place I can use this kind of control is in a routine for writing debugging messages to a text file, and optionally to the screen. So for one of these routines, I'd probably want a flag saying whether or not to write to the screen, and another to specify if it's an error message (in which case write to the screen and ignore the other flag), and maybe two more for telling the routine when I'm entering a routine and exiting a routine (to keep track of the call stack, so to speak).

So in this case, I'd need to have four flags I'm setting to true or false every time I call this writing routine. And, if I want to add another flag, I have to change all the calls I've made to this routine to match up with the new flag, since SCL doesn't give you the ability to add optional arguments.


So, rather than deal with this issue of having a flag variable for each option I want to add in a routine, I can instead take advantage of the nature of binary numbers in the computer. Before I continue, keep in mind that I didn't major in computer science or computer anything, so my explanation will probably sound hokey and not quite right.

A computer deals with numbers using binary, where we have a set of numerals that can have a value of zero or one. Each numeral you add on adds a power of two (rather than 10 like in our base-10 system). So, for instance, 1 in binary comes out to 2 to the power of 0, or 1. 10 in binary comes out to 0 to the power of 0 (0) plus 2 to the power of 1 (2) = 2. 100 comes out to 0^0 + 0^1 + 2 ^2 = 4. 1010 comes out to 0^0 + 1^1 + 0^2 + 2^3 = 10

Hopefully, if I did that right, you'll see a pattern where each digit we add onto the left adds another power of 2. 1 = 1, 10 =2 , 100=4, 1000=8, 10000=16, and so on. By seeing this pattern, we can also see that we could use a binary integer to store a series of yes/no flags using 1 for yes and 0 for no (or whatever you want). For instance, 2 + 8 in base 10 equals 10 + 1000 in binary or 1010.

The practical upshot of all this so far is, we can now create a series of flags, each unique flag being a power of two value (1,2,4,8,16,32, and so on), and we can store all the flag values we want to activate by adding the ones we're using together.

So, to define our constants for our message logger:
WriteToScreen 1
ErrorMsg 2
EnteringRoutine 4
ExitingRoutine 8

If we want to write that we're entering a routine we'd just pass in WriteToScreen + EnteringRoutine, which would calculate to 9 in base-10, and our routine could then know which flags to activate based on that number 9.

Now, to break that 9 back up into its parts, we need to go backwards and turn a decimal number back into binary 1's and 0's. Following is a routine that'll do that for us. I'm not sure it's the most efficient, but it seems to work. It works by reading left to right in the powers of two (starting at power 8 - you could increase it if you have more flags to handle). So it starts and sees if 2^8 (256) is less than the num we're trying to break apart. If it is, we turn that flag to true, and subtract 256 from the number until we get down to the last power. In this routine we pass in the flag we want to check against, and return true if the bit we're looking at is true.

Hopefully I didn't bungle the explanation too much, but I really just wanted to have this routine up for future reference, and hopefully it gets you thinking of ways it can help you write more concise or powerful code in SCL.

routine bitwise_or( num : Integer ; against : Integer ) : Integer
Var
i : Integer
pow : Integer
sum : Integer
result : Integer
Begin
sum = num
for i = 8 to 0 by -1 do
pow = 2 ^ i
if( sum >= pow ) then
sum = sum - pow
if( pow == against ) then
result = true
break
endif
endif
endfor
return result
End

Monday, October 25, 2010

GetTickCount

Tonight I was trying to debug some slow SCL code, and wanted to pinpoint exactly which routines were taking the longest to execute. QUEST has a systime() routine that returns the number of seconds since midnight. However, I wanted more accuracy, so I needed to use the GetTickCount routine provided by the Windows API.

I can call this routine using C_EXEC in SCL, and the final routine comes out like this:

routine get_tick_count() : Integer
Const
THE_DLL 'kernel32.dll'
THE_CMD 'GetTickCount'
Var
func_return : Integer
Begin
func_return = c_exec( THE_DLL + ":" + THE_CMD )
return func_return
End

Now, I can get a bit more visibility into what's taking my logics so long to run (though be sure to disable any calls to this routine once you're ready to just run the model)

Friday, October 15, 2010

Select a Part

The other day I was working on a project where I wanted some stats on a part in a model that don't show up in the Trace Entity window. So, I went to write a macro that would let me select a part and show the information I needed. I then realized that I didn't have a routine available that would let me easily select a part, so I went about writing one. Now, it's available for download here, because it was a pain to write and now you don't have to write it too.

Thursday, September 9, 2010

eVSM and QUEST User Groups

If you read back to past posts on this blog, you'll see I do a bit of work with eVSM. Up until now, there hasn't been any organized group of eVSM users that I know of, but that's now changed. An eVSM user has started a LinkedIn group geared toward discussing eVSM, as well as how to do various things in eVSM. You have to be a LinkedIn member to join, and then you have to search for the eVSM user group. Honestly, it would be nice if we could get enough eVSM users on board to build an eVSM Stack Exhange site.

I'm hoping this community gets enough power users and casual users to build and sustain some decent conversation. Luckily, the QUEST group I set up seems to have a great core of power QUEST users (including past & current Deneb/DELMIA employees) who are able to give advice and tips on how to tackle specific problems in QUEST.

Hopefully we can say the same for the eVSM group, soon.

Wednesday, August 18, 2010

eVSM to QUEST Beta Version Now Available

Any QUEST users interested in trying our (CCAT's) eVSM to QUEST converter may now do so, if they'd like to participate in beta testing (meaning we're not sure how well it works yet on lots of different computers). So if you'd like to try it out, email me at jfournier@ccat.us and let me know.

This requires you at least have access to QUEST and Visio (you'll have to get a trial version of eVSM)

Also, more information here.

Friday, June 18, 2010

IE Stack Exchange Site

I recently advocated anyone reading this blog check out OR-Exchange. Basically, the case is/was that if OR-Exchange didn't get to a certain amount of web traffic it would be shut down, as the people behind it (Stack Exchange) have a new model where they want to create nice, high volume question and answer sites on any topic people are willing to discuss.

I've been thinking about it, and it's my opinion that OR-Exchange may be a bit too niche to be able to attract enough users to keep alive.

So I am proposing we create a Stack Exchange site on Industrial Engineering/Continuous Improvement/Systems Analysis, whatever you want to call it.

If you're interested in seeing this site come to fruition, visit:


and follow the site, and if we can get enough followers and example questions, we can move on and get a centralized, modern community started for discussing anything IE/OR/CI.

Tuesday, June 1, 2010

Number Rounding in SCL

I recently found the need to do some simple number rounding in SCL, and was able to dig these two routines out using my SCL Subroutine Indexer though the index was from a previous computer I used, and hadn't copied over to my current machine. Thankfully, Google Desktop was able to find a backup copy I had made who knows when. So, to prevent me from losing these simple functions forever, here they are.

Nothing fancy; I round a number down by converting it to an integer string, then reading it back to a number using VAL. I guess SCL will truncate a number at the decimal point when converting to an integer string (%g), rather than do any real rounding. So to round up I just round down and add one. Like I said, nothing fancy, and apparently nothing worth searching for 20 minutes over. Anyways, these would be good to keep compiled all the time.

routine round_down_to_int( num_value : Real ) : Integer
Var

int_string : String
result : Integer

Begin

result = 1
int_string = str( '%g' , num_value )
result = VAL( int_string )
return result

End
routine round_up_to_int( num_value : Real ) : Integer
Var

result : Integer
rounded_down : Integer

Begin

return round_down_to_int( num_value ) + 1

End