9front - general discussion about 9front
 help / color / mirror / Atom feed
From: Amavect <amavect@gmail.com>
To: 9front@9front.org
Subject: Re: [9front] seq: fix infinite loop
Date: Mon, 16 Aug 2021 16:45:04 -0500	[thread overview]
Message-ID: <20210816164504.4341615e@spruce.localdomain> (raw)
In-Reply-To: <CADmmOS-wcgtcQ+=c01NvssHO3=06zbQjU6NzLt_K0eOX4OQe=w@mail.gmail.com>

On Sun, 15 Aug 2021 15:02:38 -0700
Sean Hinchee <henesy.dev@gmail.com> wrote:
>     ; seq 2e16 20000000000000002
> would loop forever.
At this range, 2e16 and 20000000000000002 are represented by the same
double floating point value.

> + if(val == max)
> + break;
We can cover more cases.
For example, your patch does not fix the following:
seq 9007199254740992 9007199254740996
The issue is with floating point precision.

A double has a 52 bit mantissa, meaning that it allows 2^52 different
values before the exponent is incremented (thus, floating point.)
A double has a 11 bit exponent, and 1 sign bit.
Exponents range from −1022 to +1023, with exponents −1023 and
+1024 reserved for special numbers.

At an exponent e, the mantissa represents a value between [2^e,2^(e+1)).
The precision is range/buckets, so we can calculate the precision.
At an exponent e and mantissa m, the precision is 2^(e-m)
(2^(e+1)-2^e)/2^m = 2^e/2^m = 2^(e-m)

Between [1, 2), the exponent is 0.
The precision is 2^(0-52) ≈ 0.0000000000000002220446
Between [2^52, 2^53), the exponent is 52.
The precision is 2^(52-52) = 1.

2e16 is between [2^54, 2^55), so the exponent is 54.
The precision is 2^(54-52) = 4.
Halfway ties round to the even bucket.

This is demonstrated by the following.

# infinite loop
seq 2e16 19999999999999998

# 2^53-1, halts
seq 9007199254740991 9007199254740991

# 2^53, infinite loop due to halfway tie rounding down to even bucket.
seq 9007199254740992 9007199254740992
# halts, halfway tie rounds up to even bucket, 9007199254740996
seq 9007199254740994 9007199254740994

# different due to rounding error in loss of precision
seq 5000000000000000 1.1 5000000000000002
seq 0 1.1 2


I don't believe that there is an ideal resolution to rounding error in
that last example (libmp would be too complex), but we can cover more
cases if we check that the previous val value is different from the
current val.
The correct thing to do is to throw an error warning about precision.

Thanks,
Amavect

  reply	other threads:[~2021-08-18  4:12 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-08-15 22:02 Sean Hinchee
2021-08-16 21:45 ` Amavect [this message]
2021-08-18 22:53   ` Eckard Brauer
2021-08-16 22:24 ` [9front] " Anthony Martin
2021-08-16 23:38   ` ori
2021-08-17  2:15     ` hiro
2021-08-21  1:30   ` Amavect
2021-08-18  2:49 ` [9front] " ori

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210816164504.4341615e@spruce.localdomain \
    --to=amavect@gmail.com \
    --cc=9front@9front.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).