Ответ, который вы получите от SWI, правильный.
Во многих языках программирования и практически во всех системах Prolog реализации с плавающей запятой основаны на двоичной системе (radix = 2). Число 5.3
не может быть представлено точно в этой системе, поэтому выбрано некоторое приближение. Вычитание особенно хорошо подходит для выявления таких неточностей.
?- X is 5.3-5-0.3.
X = -1.6653345369377348e-16.
Пока вы используете числа, которые являются суммой степеней двойки (включая 2 -1, 2 -2, ...), вы получите точные результаты, как насколько это позволяет точность поплавков:
?- X is 5.000244140625-5-0.000244140625.
X = 0.0.
Что должны делать ISO-совместимые системы Prolog должны - это гарантировать, что при записи числа с плавающей запятой с опцией записи quoted(true)
число с плавающей запятой записывается таким образом, чтобы его можно было точно прочитать.
Что касается вашего второго вопроса: (//)/2
определяется только для целых чисел. Если вы хотите преобразовать число с плавающей запятой в целое число, у вас есть в ISO Prolog обычные функции LIA-1:
floor/1, truncate/1, round/1, ceiling/1
.
?- X is round(5.3).
X = 5.
Однако я бы предпочел использовать (div)/2
вместо (//)/2
. Значение (//)/2
больше не поддерживается LIA-1: 2012 (стандарт ISO / IEC 10967-1: 2012) по уважительной причине. См. это и этот ответ для подробностей.
person
false
schedule
25.02.2014