mpratap@CUE.BC.CA (Matt Pratap) (05/03/91)
This may be old hat, but I just started reading this group. I need to get my programs, written in Tp5.5, to execute a procedure or flag a variable/address when a run-time error occurs, instead of exiting the program with an error. I know how to do this with dos and graphics errors. eg: if a user enters 2 real numbers and the program multiplies them together, and if the result is too large for even a real number to handle, the program will quit with an error. Instead I would like to check (via a variable or address) if the result was ok, before proceeding, else it will take steps to deal with the problem. Even my instructor ('Turbo Tom') can figure out how to do this. Thanks ------------------------------------------------------------------------- Matt Pratap, Victoria B.C. -=- mpratap@cue.bc.ca * (Insert quote here!) -------------------------------------------------------------------------
dmurdoch@watstat.waterloo.edu (Duncan Murdoch) (05/03/91)
In article <9105030125.AA18493@cue.bc.ca> mpratap@CUE.BC.CA (Matt Pratap) writes: >This may be old hat, but I just started reading this group. > >I need to get my programs, written in Tp5.5, to execute a procedure >or flag a variable/address when a run-time error occurs, instead >of exiting the program with an error. I know how to do this with >dos and graphics errors. > >eg: if a user enters 2 real numbers and the program multiplies them >together, and if the result is too large for even a real number to >handle, the program will quit with an error. >Instead I would like to check (via a variable or address) if the >result was ok, before proceeding, else it will take steps to >deal with the problem. This is hard. The Turbo and Object Professional packages from TurboPower allow automatic recovery from some errors, but not floating point errors. For those, the only way I know of is as follows: Run in the N+ state (i.e. use the IEEE reals, not the TP "real" type). Then before a questionable instruction, set the control word of the coprocessor so that all errors are masked. This seems to work with the emulator too, so it doesn't matter if you really have an 87. Your calculation is then guaranteed to succeed, but it may contain a non-numeric answer. There are a few things you could do at this point. You could just go on with the work, if answers like +INF and NAN don't bother you; the coprocessor is designed so that they propagate more or less the way you'd expect, and TP knows how to print them. You could check whether the answer is numeric or not, and proceed accordingly. You could query the coprocessor to find out whether any exceptions have occurred. Records of exceptions are kept up until the next query, which makes this sound like the best way to go, except for one bug in TP: any time you do I/O on floating point values the flags are reset, so that you lose any record of whether an error has occurred or not. There's code to help you do this in the Turbo/Object Professional toolkits; it's not too hard to write if you're comfortable in assembler. Here's a routine to do the check for a numeric answer, for the Double type: type Float = Double; Float_as_Words = array[1..4] of Word; function Is_Numeric(x : Float) : Boolean; var xw : Float_as_Words absolute x; begin Is_Numeric := (xw[4] and $7fff) < $7ff0; end; I hope this helps. Duncan Murdoch
CDHWilli@exua.exeter.ac.uk (Charles Williams) (05/05/91)
# #>eg: if a user enters 2 real numbers and the program multiplies them #>together, and if the result is too large for even a real number to #>handle, the program will quit with an error. #>Instead I would like to check (via a variable or address) if the #>result was ok, before proceeding, else it will take steps to #>deal with the problem. # #This is hard. The Turbo and Object Professional packages from TurboPower #allow automatic recovery from some errors, but not floating point errors. #For those, the only way I know of is as follows: # #[IEEE stuff, FPU modes etc] # Checking status bits and using IEEE (pronounced I-trickery?) is fast but if portability is important then there are other approaches which are worth thinking about...for example: Q) Will A*B overflow? A) overflow:=(ln(MinReal+abs(A))+ln(MinReal+abs(B)))>ln(MaxReal); Q) Will A/B overflow? A1) overflow:=(ln(MinReal+abs(A))-ln(MinReal+abs(B)))>ln(MaxReal); A2) overflow:=abs(A/MaxReal)>abs(B); Where MaxReal and MinReal are the smallest and largest normalised postive reals. If you've got a good elementary function library then taking logs is remarkably fast. (If you want to hack-up the speed a bit then you can use variant record structures to extract the binary exponents from the reals by overlaying with a set and a couple of integers and use them in place of the logs, but then you're back in the tar-pit again...) =============================================================================== ================== World's most embarassing alias: l 'ls *.f' ================= ===============================================================================
Kai_Henningsen@ms.maus.de (Kai Henningsen) (05/08/91)
Matt Pratap mpratap%CUE.BC.CA @ SUB schrieb am 02.05.1991, 23:25 MP>This may be old hat, but I just started reading this group. MP> MP>I need to get my programs, written in Tp5.5, to execute a procedure MP>or flag a variable/address when a run-time error occurs, instead MP>of exiting the program with an error. I know how to do this with MP>dos and graphics errors. Look in the manuals under "ExitProc", for a start. When you need to return to a higher level from there, I'll look where I left my assembler functions to do what C calls a longjmp(). MfG Kai