Path: ...!feeds.phibee-telecom.net!weretis.net!feeder8.news.weretis.net!reader5.news.weretis.net!news.solani.org!.POSTED!not-for-mail From: Mild Shock Newsgroups: comp.lang.prolog Subject: Re: New milestone float formatting [LoL] (Was: Request for comments, Novacore the sequel to ISO modules) Date: Sun, 28 Jul 2024 14:38:17 +0200 Message-ID: References: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit Injection-Date: Sun, 28 Jul 2024 12:38:14 -0000 (UTC) Injection-Info: solani.org; logging-data="502452"; mail-complaints-to="abuse@news.solani.org" User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:91.0) Gecko/20100101 Firefox/91.0 SeaMonkey/2.53.18.2 Cancel-Lock: sha1:dwbQXG4t3BrH9QDFAmiEGOM2dyQ= X-User-ID: eJwFwQkBwDAIA0BL/CRyoGv9S9hdemmdjsqKfPkKShUNlDkktZbH4hBj0kr7gEaYxHQ6xuVi7/UlOdyHH/qfE84= In-Reply-To: Bytes: 3344 Lines: 77 Further test cases are: ?- X is 370370367037037036703703703670 / 123456789012345678901234567890. X = 3.0000000000000004. ?- X is 0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1. X = 0.7999999999999999. The first test case doesn't work in SWI-Prolog since recently it has improve its realization of (/)/2 arithemetic function. While in most Prolog systems we should have the above result, since neither the division equals 3.0 nor the sum equals 0.8 when we use floating point numbers, and when we convert first to floating point number before doing the division. The adaptive algorithm is more expensive than just calling num.toPrecision(17). It will in mimimum call num.toPrecision(16) and do the back conversion, i.e. Number(res). So unparsing has a parsing cost. And for critical numbers, it has a second unparsing via num.toPrecision(17) cost. But I guess we can accept this little slow down. Mild Shock schrieb: > Hi, > > To capture some critical examples of float to string > conversion I went with this kind of little excess > precision and had this float to string conversion: > >          return shape_number(num.toPrecision(17)); > > Which gives this unfortunate result, still in release > 1.2.1 of Dogelog Player for JavaScript seen: > > ?- between(1,10,N), X is (20+N)/10, write(X), nl, fail; true. > 2.1000000000000001 > 2.2000000000000002 > 2.2999999999999998 > 2.3999999999999999 > 2.5 > 2.6000000000000001 > 2.7000000000000002 > 2.7999999999999998 > 2.8999999999999999 > 3.0 > > One work around is to check whether precision 16 would > also work. Like this code here: > >         let res = num.toPrecision(16); >         if (Number(res) === num) { >             return shape_number(res); >         } else { >             return shape_number(num.toPrecision(17)); >         } > > The results are much more eye friendly: > > ?- between(1,10,N), X is (20+N)/10, write(X), nl, fail; true. > 2.1 > 2.2 > 2.3 > 2.4 > 2.5 > 2.6 > 2.7 > 2.8 > 2.9 > 3.0 > true. > > Can we accept this solution? Will it slow down printing?