Сообщество программистов Autodesk в СНГ

ADN Club => AutoLisp / VisualLISP и DCL => Тема начата: Балиев от 05-08-2015, 18:15:10

Название: AutoLISP глючит или я что-то недопонимаю.
Отправлено: Балиев от 05-08-2015, 18:15:10
С недоумением обнаружил, что выражение (числа могут быть любыми):
(< (- 1.3 1.1) 0.1) принимается AutoLISP'ом как истинное (T).
Стал разбираться. Выяснилось, что граница этого чуда находится на 16 знаке после запятой. Т.е. выражение:
(< (- 1.3000000000000001 1.1) 0.2)генерирует T, а выражение:
(< (- 1.300000000000001 1.1) 0.2)уже генерирует nil

Что это было: глюк AutoLISP'а или я матчасть недоучил?
Название: Re: AutoLISP глючит или я что-то недопонимаю.
Отправлено: Александр Ривилис от 05-08-2015, 18:20:40
С недоумением обнаружил, что выражение:
Код: [Выделить]

(< (- 1.3 1.1) 0.1)

принимается AutoLISP'ом как истинное (T).

Вообще-то nil:
Цитировать
Command: (< (- 1.3 1.1) 0.1) nil

Почитай про плавающую арифметику, про количество значащих цифр в числе типа double, про ошибки округления.
Название: Re: AutoLISP глючит или я что-то недопонимаю.
Отправлено: Балиев от 05-08-2015, 18:27:35
Сорри, опечатка вышла. Вместо:
(< (- 1.3 1.1) 0.1)читать
(< (- 1.3 1.1) 0.2)
Название: Re: AutoLISP глючит или я что-то недопонимаю.
Отправлено: Александр Ривилис от 05-08-2015, 18:29:26
Сорри, опечатка вышла
Тем не менее всё, что я написал ниже справедливо.
Число двойной точности (https://ru.wikipedia.org/wiki/%D0%A7%D0%B8%D1%81%D0%BB%D0%BE_%D0%B4%D0%B2%D0%BE%D0%B9%D0%BD%D0%BE%D0%B9_%D1%82%D0%BE%D1%87%D0%BD%D0%BE%D1%81%D1%82%D0%B8).
Название: Re: AutoLISP глючит или я что-то недопонимаю.
Отправлено: Балиев от 05-08-2015, 18:36:36
Чтобы не было сомнений в чуде. :)
Название: Re: AutoLISP глючит или я что-то недопонимаю.
Отправлено: Александр Ривилис от 05-08-2015, 18:38:49
Чтобы не было сомнений в чуде.
Я уже третий раз пишу, что это не чудо. И что именно так и должно быть. И это не зависит от языка программирования, а зависит от архитектуры процессора, количества значащих цифр в плавающем числе.
Название: Re: AutoLISP глючит или я что-то недопонимаю.
Отправлено: Балиев от 05-08-2015, 18:51:31
Но там же  сравниваются два одинаковых числа с плавающей запятой. Если это не так, то в какой момент вычисления образуется разница? Более того, Если ты, скажем, напишешь так:
(setq a (- 1.3 1.1))
(< a 0.2)

То результат будет T. Ты уверен, что так и должно быть?
Название: Re: AutoLISP глючит или я что-то недопонимаю.
Отправлено: Александр Ривилис от 05-08-2015, 18:59:36
То результат будет T. Ты уверен, что так и должно быть?
Да. Учи матчасть.
Прекрасная статья для этого: http://habrahabr.ru/post/112953/
Название: Re: AutoLISP глючит или я что-то недопонимаю.
Отправлено: Александр Ривилис от 30-08-2016, 13:37:41
Обнаружился клиент, которому я не могу объяснить про хранение плавающих (double), и точность округления: http://forums.autodesk.com/t5/objectarx/convert-string-to-double-problem-tstof/td-p/6528442
Увы, но и такое бывает...  ???
Название: Re: AutoLISP глючит или я что-то недопонимаю.
Отправлено: Владимир Шу от 30-08-2016, 14:38:24
Вот тут популярно об этом говорят:
оригинал:

русская версия

Название: Re: AutoLISP глючит или я что-то недопонимаю.
Отправлено: BearDyugin от 08-02-2018, 07:59:22
Столкнутся с похожей ситуацией...
Цитировать
Команда: (+ 40.26 285100.0)
285140.0
Но я жду от этого вычисления 285140.26
Как быть? и как вообще с этим жить?
Название: Re: AutoLISP глючит или я что-то недопонимаю.
Отправлено: Алексей Кулик от 08-02-2018, 08:49:25
Чего?? А поподробнее? :)
Название: Re: AutoLISP глючит или я что-то недопонимаю.
Отправлено: BearDyugin от 08-02-2018, 08:54:51
Что мне возвращает AutoCAD ну или Lisp кто-то из них
(+ 40.26 285100.0) -> 285140.0
(+ 40.26 85100.0) -> 85140.3
(+ 40.26 5100.0) -> 5140.26
(+ 40.26 100.0) -> 140.26


А я хочу получать во всех случаях .26 на конце
 


Название: Re: AutoLISP глючит или я что-то недопонимаю.
Отправлено: Алексей Кулик от 08-02-2018, 08:57:39
(mapcar '(lambda(x) (rtos (+ 40.26 x) 2 )) '(285100. 85100. 5100. 100.)) ; '("285140.26" "85140.26" "5140.26" "140.26")

Может, вопрос в представлении?

P.S. Как раз о точности:
(mapcar '(lambda (x) (rtos (+ 40.26 x) 2 14)) '(285100. 85100. 5100. 100.)) ; '("285140.26" "85140.25999999999" "5140.260000000001" "140.26")
Название: Re: AutoLISP глючит или я что-то недопонимаю.
Отправлено: BearDyugin от 08-02-2018, 09:04:28
Может, вопрос в представлении?
Точно!

Но всё равно странно, в общем я это значение в exl передавал, и оно туда прилетало именно как мне в Lisp представляло, а с rtos всё нормуль, спасибо большое, а то я уже испугался...
Название: Re: AutoLISP глючит или я что-то недопонимаю.
Отправлено: Александр Ривилис от 08-02-2018, 14:44:24
BearDyugin
Не пользуешься поиском. Это на форуме уже обсуждалось. В командную строку AutoCAD действительное число выводится с точностью 6 десятичных знаков (всего 6 знаков, а не после запятой). Поэтому чем больше число (десятичных разрядов), тем меньше у него знаков после запятой, которые выводятся в командную строку. При этом само число хранится в 64-битах, что обеспечивает точность до 16 десятичных знаков.
Название: Re: AutoLISP глючит или я что-то недопонимаю.
Отправлено: BearDyugin от 08-02-2018, 15:37:47
Не пользуешься поиском. Это на форуме уже обсуждалось.
Я извиняюсь, в Яндекс забивал, но я даже вопрос толком не знал как сформулировать, писал что-то вроде "Lisp округляет вещественные числа" на этом форуме честно просмотрел все 6 страниц ветки про AutoLISP, из самых подходящих нашёл эту тему.
Получается vl-princ-to-string по тому же принципу работает?
Название: Re: AutoLISP глючит или я что-то недопонимаю.
Отправлено: Алексей Кулик от 08-02-2018, 15:40:02
По идее, насколько я помню, передавать надо через variant. Могу ошибаться.
Название: Re: AutoLISP глючит или я что-то недопонимаю.
Отправлено: Александр Ривилис от 08-02-2018, 15:41:35
Получается он в Excel тоже через командную строку значения передаёт, или по тем же правилам?
Нет. Вопрос о том, как ты передашь в Excel.
Название: Re: AutoLISP глючит или я что-то недопонимаю.
Отправлено: BearDyugin от 08-02-2018, 15:42:56
Быстро вы ответили с Алексеем, я сообщение уже подредактировал
Название: Re: AutoLISP глючит или я что-то недопонимаю.
Отправлено: Александр Ривилис от 08-02-2018, 15:43:11
Получается vl-princ-to-string по тому же принципу работает?
Да. Если тебе нужно определённое число знаков после запятой, то пользуйся (rtos).