Git Product home page Git Product logo

Comments (12)

Jean-Luc-Picard-2021 avatar Jean-Luc-Picard-2021 commented on July 28, 2024

Strange on my side printing 3.0000000000000004 is not
in conflict with printing 1/10. I still get:

/* Jekejeke Prolog 1.5.4 */
?- X is 1/10.
X = 0.1.

I don't know how Java does it. I guess they neither
use 17 nor 18 digits, but switch between the two,
when possible. Similarly no problem in JavaScript:

/* Dogelog Player 1.0.2, JavaScript */
?- N9 is 370370367037037036703703703670 / 123456789012345678901234567890.
N9 = 3.0000000000000004.

?- X is 1/10.
X = 0.1.

But in Python I use a more precise (/)/2, so the results
are there as follows:

/* Dogelog Player 1.0.2, Python */
?- N9 is 370370367037037036703703703670 / 123456789012345678901234567890.
N9 = 3.0.

?- N9 is 370370367037037036703703703670 / 123456789012345678901234567890 - 3.
N9 = 0.0.

?- N9 is float(370370367037037036703703703670) / float(123456789012345678901234567890) - 3.
N9 = 4.440892098500626E-16.

?- X is 1/10.
X = 0.1.

Maybe I should give JavaScript and Java also a more precise (/)/2 ?
Didn't test yet whether Python is not only precise, but also shows
good rounding in their (/)/2.

from trealla.

infradig avatar infradig commented on July 28, 2024

Another problem with 18...

$ tpl
?- X is 1/10.
X = 0.10000000000000001.
?- X is 1/3.
X = 0.33333333333333331.

It seems the last digit is subject to error so should not really be printed.

$ scryer-prolog -f
?- X is 1/3.
X = 0.3333333333333333.

from trealla.

Jean-Luc-Picard-2021 avatar Jean-Luc-Picard-2021 commented on July 28, 2024

Well usually people use the predicate format/2 if they want to see less,
don't they? And for indempodent input/output the predicate
write/1 needs to show more?

format(+Format, :Arguments)
e
Output next argument as a floating point number in exponential notation.
The numeric argument specifies the precision. Default is 6 digits. Exact
representation depends on the C library function printf(). This function is
invoked with the format %.e.
f
Floating point in non-exponential notation. The numeric argument defines
the number of digits right of the decimal point. If the colon modifier (:) is
used, the float is formatted using conventions from the current locale,
which may define the decimal point as well as grouping of digits left of the decimal point.
https://www.swi-prolog.org/pldoc/man?predicate=format/2

from trealla.

Jean-Luc-Picard-2021 avatar Jean-Luc-Picard-2021 commented on July 28, 2024

Concerning your examples I get, these are all systems
that can also show 3.0000000000000004:

/* Java,  JavaScript and Python */
?- X is 1/3.
X = 0.3333333333333333.

For example in JavaScript I use this routine:

        let res = norm_float_string(num.toPrecision());
        if (res.lastIndexOf("E") === -1) {
            num = norm_float_string(num.toExponential());
            if (num.length < res.length)
                res = num;
        }

The methods toPrecision() and toExponential() are
called without specifying a fraction length, the routines
decide by themselves whether 17 or 18 should be used.

I don't know what tricks or libraries are around in C or
C++ to archive the same.

from trealla.

infradig avatar infradig commented on July 28, 2024

from trealla.

infradig avatar infradig commented on July 28, 2024

Ok, I've had a go at it, see devel branch.

from trealla.

Jean-Luc-Picard-2021 avatar Jean-Luc-Picard-2021 commented on July 28, 2024

BTW: SWI-Prolog is full of bugs, I get this strange result, a
bigger numerator, leads to a smaller result?

/* SWI-Prolog 8.5.17 */
?- N9 is 370370367037037036703703703670 / 123456789012345678901234567890.
N9 = 3.

?- N9 is 370370367037037036703703703671 / 123456789012345678901234567890.
N9 = 2.9999999999999996.

Python doesn’t have this bug:

/* Python 3.11.0rc1 (main, Aug  8 2022, 11:30:54) */
>>> 370370367037037036703703703670 / 123456789012345678901234567890
3.0
>>> 370370367037037036703703703671 / 123456789012345678901234567890
3.0

from trealla.

infradig avatar infradig commented on July 28, 2024

from trealla.

Jean-Luc-Picard-2021 avatar Jean-Luc-Picard-2021 commented on July 28, 2024

This is also a nice test case:

/* Scryer, SWI-Prolog and Jekejeke */
?- X is 0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1.
   X = 0.7999999999999999.

/* Trealla 2.7.15 */
?- X is 0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1.
   X = 0.79999999999999993.

I think 18 digits might be too much?

from trealla.

Jean-Luc-Picard-2021 avatar Jean-Luc-Picard-2021 commented on July 28, 2024

Now its overshooting in the other direction. Was
expecting that when it shows 0.8, I can also subtract 0.8 and get zero?

Trealla Prolog (c) Infradig 2020-2023, v2.9.4
?- X is 0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1.
   X = 0.8.
?- X is 0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1-0.8.
   X = -1.1102230246251565e-16.

from trealla.

Jean-Luc-Picard-2021 avatar Jean-Luc-Picard-2021 commented on July 28, 2024

Thanks to format/2 can investigate the case in more detail.
The number seems to be a challenge for the "g" format:

/* Java, JavaScript and Python */
?- X is 370370367037037036703703703670 / 123456789012345678901234567890,
    format('~16g~n', [X]).
3

?- X is 370370367037037036703703703670 / 123456789012345678901234567890,
    format('~17g~n', [X]).
3.0000000000000004

But the other test case is not so much affected, except for a difference in Java:

/* Java, JavaScript and Python */
?- X is 0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1, format('~16g~n', [X]).
0.7999999999999999

/* JavaScript and Python */
?- X is 0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1, format('~17g~n', [X]).
0.79999999999999993

/* Java */
?- X is 0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1, format('~17g~n', [X]).
0.7999999999999999

from trealla.

Jean-Luc-Picard-2021 avatar Jean-Luc-Picard-2021 commented on July 28, 2024

Since Trealla Prolog can produce the same:

/* Trealla Prolog 2.14.32 */
?- X is 370370367037037036703703703670 / 123456789012345678901234567890,
    format('~16g~n', [X]).
3

?- X is 370370367037037036703703703670 / 123456789012345678901234567890,
    format('~17g~n', [X]).
3.0000000000000004

?- X is 0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1, format('~16g~n', [X]).
0.7999999999999999

?- X is 0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1, format('~17g~n', [X]).
0.79999999999999993

Maybe there is no harm in that the top-level doesn't show that much precision.

So I am closing this ticket.

from trealla.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.