 |
forums.silverfrost.com Welcome to the Silverfrost forums
|
View previous topic :: View next topic |
Author |
Message |
hdalgarno
Joined: 27 Jun 2013 Posts: 8
|
Posted: Thu Jun 27, 2013 12:54 pm Post subject: Test for intentionally undefined variables? |
|
|
(I am using F90/95 with the FTN95 Silverfrost compiler)
Is it possible to test for an undefined variable, that is intentionally undefined unless some event has occured?
For example, lets say I define X to be an integer but give it no initial value. During the course of the program X will be given a value ONLY if an event Y occurs. Later, I would like to initiate one set of commands if event Y has occured, and another set if it has not occured. I'd like to know whether I can test X to ask if it is undefined, or if it has a value, and use the outcome of this test to select which set of commands to initiate.
I realise that I could use a flag that is set when event Y occurs but I have limited flexibility to introduce new variables to this particular application, so an ability to test the existing variable X would be the preferred first solution.
I'd really appreciate any advice on this |
|
Back to top |
|
 |
LitusSaxonicum
Joined: 23 Aug 2005 Posts: 2402 Location: Yateley, Hants, UK
|
Posted: Thu Jun 27, 2013 1:53 pm Post subject: |
|
|
There is no bit pattern in an INTEGER that reflects an undefined number, as all possible bit patterns represent positive and negative values including zero. There may be a bit pattern for a floating point (REAL) number that reflects that undefined status, but the test could be quite difficult - I've certainly never tried to use it.
What about using a LOGICAL variable? This only has two states, .TRUE. or .FALSE. and they are held in FTN95 to be the same bit patterns as 0 or 1 if the byte(s) are part of an INTEGER. That gives some bit patterns that neither mean .TRUE. or .FALSE. You could start your program by setting a LOGICAL variable the value 'FALSE., say in BLOCK DATA, or if you don't like that, in a routine called at startup. Later in your program, you could set the variable to .TRUE. if event Y occurs. Then you could test .TRUE. or .FALSE. like this:
Code: | IF (QUERY_EVENT_Y) THEN
...
ELSE
...
ENDIF |
(The ELSE is effectively IF (.NOT. Query_Event_Y) )
Similarly, you could have a CHARACTER*(1) variable that could record a whole alphabet of event types.
In every case, you would have to provide an initial value that represented 'no event'.
I have always wondered what would happen in a LOGICAL*(1) variable to the bit patterns that neither represent .TRUE. nor .FALSE. (0 or 1). Presumably, one could get at them by EQUIVALENCEing the LOGICAL to an INTEGER, or by judicious use of COMMON, but what are your chances of understanding what you intended next week, let alone decades later?
Eddie |
|
Back to top |
|
 |
hdalgarno
Joined: 27 Jun 2013 Posts: 8
|
Posted: Thu Jun 27, 2013 3:07 pm Post subject: |
|
|
Hi Eddie
Thanks for your repsonse...I'm coming round to the idea that there is no other option than to test event Y by adding a flag. I'm surprised that Fortran doesn't have some sort of functionality to test for undefined variables.
What I have is something analagous to this:
integer :: X, Y
logical :: event = .false.
IF (event) then
X = 1
ENDIF
Y = X + 2
and I have to wait for runtime for it to fall over before it would tell me that X is undefined.
Whereas what I want is something like this:
integer :: X, Y
logical :: test, event
event = .false.
IF (event) then
X = 1
ENDIF
test = 'does X have a value?'
IF (test) then
Y = X + 2
ELSE
Y = X + 3
ENDIF
It seems sensible to me that Fortran should be able to do this, since it can detect a variable is undefined at runtime, but it appears it's not possible  |
|
Back to top |
|
 |
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 8210 Location: Salford, UK
|
Posted: Thu Jun 27, 2013 4:34 pm Post subject: |
|
|
FTN95 offers two predefined states. The compiler option /ZEROISE presets all variables to zero (I don't recall the details here) whilst the option /UNDEF presets all reals and integers to a certain bit pattern and flags a runtime error when the value is used before being set. Naturally there is a runtime overhead when using /UNDEF. /UNDEF is part of /CHECKMATE.
Basically you can do your own initialisation as long as you use values that can never occur naturally in your model. This is tricky for integers (/UNDEF uses 0x80808080 I think). For reals the ASCII standard defines NAN (not a number). I would have to look up if FTN95 supports this in any way. |
|
Back to top |
|
 |
LitusSaxonicum
Joined: 23 Aug 2005 Posts: 2402 Location: Yateley, Hants, UK
|
Posted: Thu Jun 27, 2013 4:44 pm Post subject: |
|
|
... but X and Y, being INTEGERs are never undefined, as there is no pattern of bits that represents undefined for an integer. It's easy to prove this for an INTEGER*(1), because you can write out all the patterns, and see that they go from -254 ... 0 ... +255. There is a pattern of bits that represents undefined for a real - but difficult to test for it.
If you use a flag, then all you need to do is set it during the event. A flag of LOGICAL type is best because the test is simplest, but an INTEGER allows you to count the events.
Eddie |
|
Back to top |
|
 |
JohnCampbell
Joined: 16 Feb 2006 Posts: 2615 Location: Sydney
|
Posted: Fri Jun 28, 2013 4:54 am Post subject: |
|
|
hdalgarno,
FTN95 can indicate a variable is undefined by setting it to an initial value that represents that it is undefined. ( not sure what this value is, but it can occur)
To achieve what you want, there must be a value of X which implies it is definately undefined. Often 0, -1 or 9999999 are values that suit that purpose and it is probably better to choose your own.
I would recommend that you initialise X to a value that is not sensible for it's use, so testing if X is set to this non-sensible value implies it's use is not required.
Alternatively you can use a logical variable, such as Use_X, which indicates the same, in a more elegant form.
It is often easier to have "X = -1" and test "if (X /= -1) then ..."
For real variables, I also have declared
REAL*8, PARAMETER :: DUMMY = -.99898 ! special coordinate for undefined coordinates
and test " IF (Y == dummy) ... "
Over many years of use I am yet to get this value being a valid number and cause a problem.
You just have to put up with the WARNING - 179: Comparing floating point quantities for equality may give misleading results
John |
|
Back to top |
|
 |
hdalgarno
Joined: 27 Jun 2013 Posts: 8
|
Posted: Mon Jul 01, 2013 1:40 pm Post subject: Re: |
|
|
JohnCampbell wrote: | I would recommend that you initialise X to a value that is not sensible for it's use, so testing if X is set to this non-sensible value implies it's use is not required.
|
Dear John,
many thanks for this! This is the solution that I used and it works well - my 'undefined' variable represents a time value so I have initialised this to a negative number which is clearly unphysical and also easy to test.
To all other people that posted advice - many thanks, it was much appreciated! |
|
Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|