Path: csiph.com!news.mixmin.net!eternal-september.org!reader01.eternal-september.org!.POSTED!not-for-mail From: Tim Rentsch Newsgroups: comp.programming Subject: Re: A little puzzle. Date: Mon, 28 Nov 2022 07:22:33 -0800 Organization: A noiseless patient Spider Lines: 81 Message-ID: <86tu2j6r46.fsf@linuxsc.com> References: <875yf8nijb.fsf@bsb.me.uk> <42d09790-8473-4d9a-bc3f-35ed25e84b54n@googlegroups.com> <86y1rv7oeu.fsf@linuxsc.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Injection-Info: reader01.eternal-september.org; posting-host="8f857c192f6688ee1cdff50f6ccf3164"; logging-data="2105498"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1+6ll0D2ZYIr0DoAS1UUhHLL18qwv2YCEA=" User-Agent: Gnus/5.11 (Gnus v5.11) Emacs/22.4 (gnu/linux) Cancel-Lock: sha1:ex+LMH9cNV4/iBYnMs7yXwBBYt0= sha1:kAYPCv74cY87BjD9Bo43qfTsp5Q= Xref: csiph.com comp.programming:15982 Julio Di Egidio writes: > On Monday, 28 November 2022 at 04:23:28 UTC+1, Tim Rentsch wrote: > >> Julio Di Egidio writes: I recommend switching away from google groups, to a posting service that is more well-behaved. Try eternal-september.org, which offers free accounts after registering, if you can't find anything else more to your liking. >>> On Monday, 21 November 2022 at 21:45:34 UTC+1, Ben Bacarisse wrote: >>> >>>> Consider any ordered measure that "wraps round" -- bearings in >>>> degrees, minutes in the hour, indeed hours in either the 12 or 24 >>>> hour clock. The problem is to determine if a given value is in >>>> the sub-range specified by a start and an en value. > > > >>> In terms of remainder (as in JS), MOD looks like this: >>> >>> ```js > > Should have been "ts", i.e. TypeScript (for the few type > annotations: get rid of those to get the plain JS). > >>> ```js >>> function MOD(x: number, m: number): number { >>> if (x * m === 0) { return 0; } // allow for MOD(x, 0) > > BTW, better not do that multiplication: > > ```js > if (m === 0) { return 0; } // allow for m = 0 > if (x === 0) { return 0; } // a short-cut > ``` > > Moreover, notice that this MOD fails (in particular, does not > return positive) for m <= 0. (!!) But I won't bother with that > now. > >>> if (x > 0) { x = x % m; } >>> else { x = (m + x % m) % m; } >>> return x; >>> } >>> ``` >> >> This proposed function doesn't work. Consider a curfew that >> starts at 10 pm (2200) and goes until 5 am (0500). Is 3 am >> (0300) a curfew violation? The call to your function would be >> >> inOpenModRange( 0300, 2200, 0500, 2400 ); >> >> which yields false. But it should yield true. > > Argh! But you should not have snipped that "beware > of bugs", that was the most important part!! ;) It's your job to beware of bugs, not mine. > This one should do the trick: > > ```ts > /** Returns whether x in [lo, hi[ (mod m). */ > function inOpenModRange( > x: number, lo: number, hi: number, m: number > ): boolean { > let x_ = MOD(x - lo, m); > let hi_ = MOD(hi - lo, m); > return x_ < hi_; > } > ``` This scheme looks like it will work, as long as the values given don't get too near the edges of representation. JavaScript represents numeric values using floating point, and that choice leads to some unexpected results when working with large numbers. However, this approach is more complicated than it needs to be. Have you tried looking at the other answers?