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?