markh@csd4.milw.wisc.edu (Mark William Hopkins) (02/04/89)
This problem was recently posed: Find a suitable translation in C for a, b, c: CHAR ... FOR c := a TO b DO <Body> that correctly accounts for c's remaining inside its subrange 0..127 or 0..255 or whatever. The answer is this: for (c = a; c < b; c++) <Body> if (c = b) <Body> Of course, if you want to avoid duplication, you can go something like this: for (c = a; c <= b; if (c < b) c++) <Body>
gwyn@smoke.BRL.MIL (Doug Gwyn ) (02/04/89)
In article <763@csd4.milw.wisc.edu> markh@csd4.milw.wisc.edu (Mark William Hopkins) writes: >Of course, if you want to avoid duplication, you can go something like this: > for (c = a; c <= b; if (c < b) c++) <Body> There is a solution but that ain't it.
msb@sq.uucp (Mark Brader) (02/09/89)
> Find a suitable translation in C for > a, b, c: CHAR > ... > FOR c := a TO b DO <Body> > > that correctly accounts for c's remaining inside its subrange 0..127 or > 0..255 or whatever. I haven't seen the following answer yet. (I'm sure that net propagation delay means that I'll see three such answers tomorrow, but anyway....) As a non-speaker of Modula2, I am assuming that the original statement calls for the greater of 0 and b-a+1 iterations, i.e., including both the a and b cases if a >= b but nothing if a < b. Otherwise it'd be simple. The problem is of course that c might loop through all values that its type can hold, so there's no single test such as c < b that you can use in a for- or while-header, no matter how you fiddle the increment side. However, this doesn't mean that you have to repeat the whole body. Just provide a separate test before the first iteration: if (a <= b) { c = a; do { <Body> } while (c++ < b); } This does what was asked for -- and yes, I tested it. So you might keep it in mind the next time you need a loop whose index that might exactly reach the minimum legal maximum value for its data type. But I don't think it really meets the requirement of a *suitable* C translation... it's more of a transliteration. A suitable C translation would use the suitable datatype for a loop index whose absolute value doesn't exceed 32767: int. Since the loop index isn't going to reach 32767, the loop can now be coded in (wait "for" it) a straight"for"ward fashion: for (c = a; c <= b; ++c) { <Body> } Of course, the loop body might have to be altered if it does something that depends on the type of the loop index being char. Such things are relatively rare, usually involving & operations. Mark Brader, Toronto sed -e "s;??\\([-=(/)'<!>]\\);?\\\\?\\1;g" utzoo!sq!msb, msb@sq.com will fix them... -- Karl Heuer
ark@alice.UUCP (Andrew Koenig) (02/09/89)
In article <1989Feb8.183945.21485@sq.uucp>, msb@sq.uucp (Mark Brader) writes: > if (a <= b) { > c = a; > do { > <Body> > } while (c++ < b); > } > This does what was asked for -- and yes, I tested it. So you might Even though you tested it, it's wrong. The last time through the loop, c == b. Thus after exiting from the loop, c == b+1. This violates the conditions of the problem. (imagine a machine that checks for integer overflow) -- --Andrew Koenig ark@europa.att.com