prknoerr@immd4.informatik.uni-erlangen.de (Peter Knoerrich) (06/27/91)
Ok, here you are, the third one: This one needs some warnings, for it will for sure not run on any compiler. For instance, you need a word data type which is not implemented on most unix pc compilers (for some good reason, agreed). But I think most of you guys either use Borland's TurboPascal or perhaps some other pascal which does have unsigned data types, so you will perhaps be able to follow this one (I know I'm advertising, but at least it's for a reasonable product I do it for) program AdjustValue; procedure AdjustAndTrim(var value : word;change : integer); var temp : integer; begin temp := value + change; if (temp<0) then temp := 0 else if (temp>1000) then temp := 1000; value := temp; end; var given : word begin given := 0; AdjustAndTrim(given,-1); end. The "AdjustAndTrim"-procedure should add or subtract a shift to a word, cutting off too low and too high values to stay inside a constant range (0 .. 1000 here). As the programmer (that is me) anticipated there will be some negative values at first, he chose to put the sum into an integer first, checking whether it was legal, doing then some trimming and as the last operation copy the valid value back into the original word variable. What goes wrong is the following: Even the first assignment fails. Though an integer has been provided to catch up with those negative fellows, a range check error will occur when called with the given parameters. Now, who of you pascalaholics can guess what went wrong? And where do the other puzzles stay I keep scanning the group for? Does Arthur Dent after all find out what the question to 42 is? Drop a word! Bye, Peter PS: If I happen to type in junk, and the intended solution won't work (perhaps because the compiler yells at some typo error), please supply me not only with the solution but also with corrections/ better solutions/enhanced puzzles. This is called cooking and counts double.I will then take the thing home to my trusty 286 and figure out my errors. Seemingly one such thing has happened to the last puzzle, but as I were sure I did exactly such a thing myself some time ago, I have still to check it out. Keeping watching for my next post next week, which will also contain the solution to the first puzzle!) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PPS: Somebody suggested I should also post puzzles of the kind: Which variable declarations would be necessary to make the following source code compilable: [figure your own example (and in case of agreement, also post it)] ? But in my opinion this sounds a bit to much like theory, where I prefer the "will compile, but produce unexpected results"-kind of puzzles, as they have an air of praxis (BTW, do you use the verb praxis here?) Any opinions are welcome. --- sig? You must be kidding with all those SIGKILLs around on this machine! Peter Knoerrich, email: prknoerr@faui43.informatik.uni-erlangen.de
sml@ssc-vax (Stuart Lewis) (06/29/91)
In article <1991Jun27.131018.26430@informatik.uni-erlangen.de> prknoerr@immd4.informatik.uni-erlangen.de (Peter Knoerrich) writes: >Ok, here you are, the third one: > >This one needs some warnings, for it will for sure not run on >any compiler. For instance, you need a word data type which >is not implemented on most unix pc compilers (for some good >reason, agreed). > >But I think most of you guys either use Borland's TurboPascal >or perhaps some other pascal which does have unsigned data types, >so you will perhaps be able to follow this one (I know I'm >advertising, but at least it's for a reasonable product I do it for) > I'm not sure I understand what you're telling me here about the word data type. But then, I program on the VAX - not on pc's (not until this fall anyway). Given that forewarning about my lack of pc Pascal, let me approach your code from a standard VAX Pascal point of view....... >program AdjustValue; > (* the var declaration must be here - not after the procedure *) (* that *immediately* will give compile time errors *) VAR (* from below *) given : word; (* from below *) >procedure AdjustAndTrim(var value : word;change : integer); (* ^^^^^^ since "change" is always -1, it would be 'tidier' to declare it as a constant up above and not worry about passing it *) > var > temp : integer; > begin > temp := value + change; (* I don't know what TYPE "word" is (pc exclusive?), but this last line will not work unless "value" (VAR'd "given") is ultimately either an INTEGER value or CHAR value, because "temp" is declared as type INTEGER. You can declare a data type word = INTEGER; up above your global VAR's, and then it would work. *) > if (temp<0) then > temp := 0 > else > if (temp>1000) then > temp := 1000; > value := temp; > end; > >var (* global VAR - delete this line - move to above *) > given : word (* ditto - plus syntax error, need ";" at end *) > >begin > given := 0; (* here again, I don't know what type "word" is, but you're assigning an INTEGER (or possibly CHAR) value to "given" - save yourself some trouble and declare it as one of those two *) > AdjustAndTrim(given,-1); >end. > [stuff deleted] > >What goes wrong is the following: Even the first assignment fails. >Though an integer has been provided to catch up with those negative >fellows, a range check error will occur when called with the given >parameters. > [stuff deleted] just a matter of personal preference or style, but here's what I would do.... PROGRAM AdjustValue (input, output); CONST change = -1; TYPE word = INTEGER; VAR given : word; PROCEDURE AdjustAndTrim (VAR value : word); VAR temp : INTEGER; BEGIN (* PROCEDURE AdjustAndTrim *) temp := value + change; IF (temp < 0) THEN value := 0 ELSE IF (temp > 1000) THEN value := 1000 ELSE value := temp; END; (* PROCEDURE AdjustAndTrim *) BEGIN (* MAIN *) write('Enter a value : '); readln(given); AdjustAndTrim(given); writeln('Adjusted value is : ', given); END. (* MAIN *) I added read & write statements - the program isn't very useful as a learning tool unless you can see what the heck it's doing! :-) Again, this is just my personal style, but it does solve the TYPE problems with "word" and "given". I didn't run this, but I'd be *real* embarassed if it crashed on somebody! >--- >sig? You must be kidding with all those SIGKILLs around on this machine! >Peter Knoerrich, email: prknoerr@faui43.informatik.uni-erlangen.de Stuart Lewis sml@ssc-vax
pshuang@athena.mit.edu (Ping-Shun Huang) (07/01/91)
To Stuart: > (* the var declaration must be here - not after the procedure *) > (* that *immediately* will give compile time errors *) One of the reasons that he specified Turbo Pascal is that this compiler is more lax than ones which are strictly compatible -- it permits you to intermix VAR, CONST, FUNCTION, and PROCEDURE declarations in any order before your main BEGIN-END pair. A word is a 16-bit integer, by the way. > (* ^^^^^^ since "change" is > always -1, it would be > 'tidier' to declare it as a > constant up above and not > worry about passing it *) Peter said that change would often be negative at first, *NOT* that it would always be -1. > (* I don't know what TYPE "word" is (pc exclusive?), but this last > line will not work unless "value" (VAR'd "given") is ultimately > either an INTEGER value or CHAR value, because "temp" is declared as > type INTEGER. You can declare a data type word = INTEGER; up above > your global VAR's, and then it would work. *) The type word is assign-compatible with integer -- when going word to integer, the value is sign-extended, when going from integer to word the extra bits are truncated. ------------------------------------------------------------------------- To Peter: Except for the below-noted typo, I can't see why this is causing the range error -- I'm a Pascalholic but the academic/real world has been forcing me to use Scheme and C instead, respectively, so my recall isn't as good as it used to be. {sigh} A couple of vague thoughts which are running through my head involve whether the TP compiler is using unsigned or signed intermediate results and the fact that an integer -1 is all binary one's in two's complement notation and therefore looks like MaxWord when casted to word. Oh, if you want to post puzzles which are clearer, be sure to be more specific about what happens. "The first assignment", where the range error occurs, is unclear; do you mean the first assignment which occurs in the source code file, or the first one which the computer executes? That sort of thing needs to be more clearly stated. If I read your posts correctly, this is being posed as a puzzle and not as a real problem you're facing which needs solution. Just in case it is the latter, though, you should be able to re-write as "IF (Value+Change)<0 THEN", i.e. process the negative sum as a special case altogether, rather than doing the sum and then correcting afterwards. > var > given : word {typo? missing a semicolon here after "word"} -- Above text where applicable is (c) Copyleft 1991, all rights deserved by: UNIX:/etc/ping instantiated (Ping Huang) [INTERNET: pshuang@athena.mit.edu]